如何在Cypress/JavaScript中按条件筛选并点击首个可用赔率按钮
需求场景
我有如下展示不同赔率的列表:
用户选择赔率按钮后会将对应选项添加至投注单,我需要选择正确的按钮:即第一个可用的赔率按钮,不能选中已禁用或已选中的赔率按钮。
我的逻辑如下:
- 查看图中的赔率列表,逐行检查行内按钮是否未被禁用且未被选中。
- 满足上述条件时,将选项名称存储为别名,再点击该赔率按钮。
目前我写的代码并不完全正确,虽然能选中一个赔率按钮,但不确定是否会校验行内按钮的禁用、选中状态。当前能选中第一个按钮是因为目前没有按钮被选中或禁用,且站点为线上环境,无法手动调整场景测试。
关联HTML代码
<div class="featuredOutright__content featuredOutright__content--primary"> <ul class="featuredOutright__markets"> <li id="betBundle__4192262052__wrapper" class="featuredOutright__selection"> <div class="marketsList__image" id="betBundle__4192262052__sportIcon"> <i class="icon-football"></i> </div> <div class="marketsList__detail"> <i class="icon-shape icon-shape--rhombus icon-odds-boost"></i> <div class="marketsList__market__title" id="betBundle__4192262052__marketTitle"> Club Brugge KV to score over 0.5 goals in each half <a class="marketsList__market__matchName textLink" href="#/soccer/event/20213522" id="betBundle__4192262052__eventLink"> Club Brugge KV - KV Oostende </a> </div> </div> <div class="marketsList__was"> <p class="marketsList__was-amount strikethrough--horizontal" id="betBundle__4192262052__previousPrice"> 5/6 </p> </div> <div class="marketsList__amount selectionBlock"> <a id="event-selection-4192262052" eventid="event-selection-20213522" title="Club Brugge KV to score over 0.5 goals in each half" eventmodule="ODDS_BOOSTS_HOMEPAGE" class="oddsBoostedPrice button__bet eventSelection--link" "=""> <i class="icon-tick"></i> <em class="button__bet__odds">10/11</em> <div class="button__bet--action" data-textadded="Added" data-textremoved="Removed"></div> </a> </div> </li> <li id="betBundle__4192270554__wrapper" class="featuredOutright__selection"> <div class="marketsList__image" id="betBundle__4192270554__sportIcon"> <i class="icon-football"></i> </div> <div class="marketsList__detail"> <i class="icon-shape icon-shape--rhombus icon-odds-boost"></i> <div class="marketsList__market__title" id="betBundle__4192270554__marketTitle"> US Lecce to score over 0.5 goals in each half <a class="marketsList__market__matchName textLink" href="#/soccer/event/20213510" id="betBundle__4192270554__eventLink"> Benevento - Lecce </a> </div> </div> <div class="marketsList__was"> <p class="marketsList__was-amount strikethrough--horizontal" id="betBundle__4192270554__previousPrice"> 3/1 </p> </div> <div class="marketsList__amount selectionBlock"> <a id="event-selection-4192270554" eventid="event-selection-20213510" title="US Lecce to score over 0.5 goals in each half" eventmodule="ODDS_BOOSTS_HOMEPAGE" class="oddsBoostedPrice button__bet eventSelection--link" "=""> <i class="icon-tick"></i> <em class="button__bet__odds">10/3</em> <div class="button__bet--action" data-textadded="Added" data-textremoved="Removed"></div> </a> </div> </li> <li id="betBundle__4196565633__wrapper" class="featuredOutright__selection"> <div class="marketsList__image" id="betBundle__4196565633__sportIcon"> <i class="icon-tennis"></i> </div> <div class="marketsList__detail"> <i class="icon-shape icon-shape--rhombus icon-odds-boost"></i> <div class="marketsList__market__title" id="betBundle__4196565633__marketTitle"> A Zverev and F Auger Aliassime to win the first set of the match <a class="marketsList__market__matchName textLink" href="#/tennis/outrights/20405610" id="betBundle__4196565633__eventLink"> Odds Boost - Tennis </a> </div> </div> <div class="marketsList__was"> <p class="marketsList__was-amount strikethrough--horizontal" id="betBundle__4196565633__previousPrice"> 7/1 </p> </div> <div class="marketsList__amount selectionBlock"> <a id="event-selection-4196565633" eventid="event-selection-20405610" title="A Zverev and F Auger Aliassime to win the first set of the match" eventmodule="ODDS_BOOSTS_HOMEPAGE" class="oddsBoostedPrice button__bet eventSelection--link" "=""> <i class="icon-tick"></i> <em class="button__bet__odds">9/1</em> <div class="button__bet--action" data-textadded="Added" data-textremoved="Removed"></div> </a> </div> </li> </ul> </div>
现有实现代码
步骤定义代码
import { Given, When, Then } from "cypress-cucumber-preprocessor/steps"; import OddsSelectionElements from '../elements/oddsSelectionElements'; const oddsSelectionElements = new OddsSelectionElements(); When ("User selects an available bet bundle selection", () => { oddsSelectionElements.featuredSelectionRow() .within(() => { oddsSelectionElements.oddsButton().first().not(".disabled"); oddsSelectionElements.oddsButton().first().not(".selected"); oddsSelectionElements.marketListTitle().first().invoke("text").as("betBundleTitle"); oddsSelectionElements.oddsButton().first().click(); }) })
OddsSelectionElements类代码
class OddsSelectionElements { oddsButton() { return cy.get('.button__bet__odds') } featuredSelectionRow() { return cy.get('.featuredOutright__selection') } marketListTitle() { return cy.get('.marketsList__market__title') } } export default OddsSelectionElements
按钮状态说明
按钮选中时会在<a>标签的class属性中添加selected类,示例如下:
<a id="event-selection-4192270554" eventid="event-selection-20213510" title="US Lecce to score over 0.5 goals in each half" eventmodule="ODDS_BOOSTS_HOMEPAGE" class="oddsBoostedPrice button__bet eventSelection--link selected" "="">
禁用状态逻辑同上,只是将selected替换为disabled类。
问题修复方案
你现有代码的核心问题有两个:
- 状态类
selected和disabled是加在<a>标签上的,而你的oddsButton()取的是<a>标签下的<em class="button__bet__odds">子元素,状态类不在这个子元素上,所以你加的not(".disabled")和not(".selected")校验完全不生效 - 你直接对所有行执行
within,又直接取first()元素,没有逐行遍历判断可用状态的逻辑,就算第一个按钮不可用也会强行点击
修复后代码
首先修改OddsSelectionElements类,直接获取带状态的<a>标签作为赔率按钮元素:
class OddsSelectionElements { // 直接取带状态属性的a标签,状态类都在这个节点上 oddsButton() { return cy.get('a.button__bet') } featuredSelectionRow() { return cy.get('.featuredOutright__selection') } marketListTitle() { return cy.get('.marketsList__market__title') } } export default OddsSelectionElements
再修改步骤定义,逐行遍历判断,找到第一个可用的按钮再操作:
When ("User selects an available bet bundle selection", () => { // 遍历所有行 oddsSelectionElements.featuredSelectionRow() .each(($row) => { // 查找当前行内的赔率按钮 const $oddsBtn = $row.find('a.button__bet') // 判断是否未禁用、未选中 if (!$oddsBtn.hasClass('disabled') && !$oddsBtn.hasClass('selected')) { // 存储选项名称 cy.wrap($row).find('.marketsList__market__title').invoke('text').as('betBundleTitle') // 点击按钮 cy.wrap($oddsBtn).click() // 找到第一个可用按钮后终止遍历 return false } }) })
以上修复逻辑会严格按照需求逐行检查按钮状态,找到第一个符合要求的可用按钮后执行存储和点击操作,不会出现选中禁用/已选按钮的问题。
内容的提问来源于stack exchange,提问作者BruceyBandit
相关产品推荐
相关产品推荐

