處理動態下拉選單是現代 Web 應用程式中的常見挑戰,特別是當下拉選項是從 API 動態取得或基於使用者互動載入時。當使用 Cypress 對此類下拉式選單進行自動化測試時,您需要確保選擇正確的選項,即使它們是在延遲一段時間後渲染的。
本部落格將引導您完成與 Cypress 中的動態下拉清單互動的過程,並提供常見場景的範例,包括由 API 回應填入的下拉清單和根據使用者輸入變更的下拉清單。
動態下拉清單通常會帶來測試挑戰,因為:
Cypress 提供了多個強大的命令來應對這些挑戰,確保您可以可靠地從動態下拉清單中選擇正確的選項。
讓我們透過一個基本範例來了解 Cypress 如何處理動態下拉式選單。
第 1 步:與下拉觸發器互動
大多數動態下拉選單最初是隱藏的,僅在使用者點擊按鈕或輸入欄位時才顯示。首先,您需要與觸發元素進行互動。
範例 HTML:
<select id="country-dropdown"> <option value="" disabled selected>Select a country</option> </select> <button id="load-countries">Load Countries</button>
模擬使用者互動:
it('should click the button to load dropdown options', () => { cy.visit('/dropdown-page'); // Visit the page with the dynamic dropdown cy.get('#load-countries').click(); // Click the button to load the dropdown options });
這會按一下按鈕,在此範例中會觸發 API 呼叫或另一個程序來動態填入下拉選項。
第 2 步:等待下拉式選單填充
在動態下拉式選單中,選項可能無法立即可用。 Cypress 可以使用諸如 should('exist') 之類的斷言或等待元素變得可用。
填充後處理下拉清單的範例:
it('should wait for dropdown options to be populated', () => { cy.get('#country-dropdown').should('exist').click(); // Click to open the dropdown // Wait for the dropdown options to populate cy.get('#country-dropdown option').should('have.length.greaterThan', 1); });
在這裡,Cypress 會等到下拉選項可用後再繼續。
第 3 步:動態選擇選項
填入下拉清單後,您可以使用 cy.select() 或直接與 DOM 元素互動來選擇所需的選項。
選擇國家的範例:
it('should select a country from the dynamic dropdown', () => { cy.get('#country-dropdown').select('India'); // Select by visible text });
如果您的下拉式選單不使用本機
it('should manually select a country from a custom dropdown', () => { cy.get('#country-dropdown').click(); // Open the dropdown // Select the desired option by clicking on the visible text cy.contains('li', 'India').click(); });
許多現代應用程式使用類型和搜尋下拉清單,使用者在輸入欄位中鍵入內容,下拉選項會根據輸入的文字動態過濾。讓我們看看 Cypress 中如何處理此類場景。
型別與搜尋動態下拉清單範例
HTML 結構範例:
<div class="search-dropdown"> <input type="text" id="search-input" placeholder="Search countries..."> <ul id="dropdown-options"> <li>USA</li> <li>Canada</li> <li>Australia</li> </ul> </div>
在這種情況下,下拉清單中的選項將根據使用者的輸入進行過濾。
第 1 步:輸入與篩選選項
當在輸入欄位中輸入內容時,Cypress 可以模擬使用者輸入並動態過濾選項。
it('should filter and select a country from a type-and-search dropdown', () => { cy.get('#search-input').type('Can'); // Type into the input field to filter options // Verify that the filtered result appears cy.get('#dropdown-options li').should('have.length', 1); // Verify that the option matches the search term cy.get('#dropdown-options li').first().should('contain.text', 'Canada'); // Click to select the filtered option cy.get('#dropdown-options li').first().click(); });
在這種情況下,下拉清單中的選項將根據使用者的輸入進行過濾。
第 1 步:輸入與篩選選項
當在輸入欄位中輸入內容時,Cypress 可以模擬使用者輸入並動態過濾選項。
it('should filter and select a country from a type-and-search dropdown', () => { cy.get('#search-input').type('Can'); // Type into the input field to filter options // Verify that the filtered result appears cy.get('#dropdown-options li').should('have.length', 1); // Verify that the option matches the search term cy.get('#dropdown-options li').first().should('contain.text', 'Canada'); // Click to select the filtered option cy.get('#dropdown-options li').first().click(); });
此程式碼模擬在搜尋框中輸入 Can,驗證下拉清單是否已過濾為僅顯示“加拿大”,然後選擇該選項。
第 2 步:等待下拉選項動態載入(API 驅動程式)
有時,類型和搜尋下拉清單由 API 支持,該 API 根據使用者的輸入返回選項。 Cypress 可以等待 API 回應並驗證選項。
it('should handle type-and-search dropdown populated by API', () => { // Intercept the API call triggered by typing cy.intercept('GET', '/api/countries?search=Can', { fixture: 'filtered-countries.json' // Mocked API response with filtered data }).as('searchCountries'); // Type into the input to trigger the API call cy.get('#search-input').type('Can'); // Wait for the API response cy.wait('@searchCountries'); // Validate the filtered results cy.get('#dropdown-options li').should('have.length', 1); cy.get('#dropdown-options li').first().should('contain.text', 'Canada'); // Select the option cy.get('#dropdown-options li').first().click(); });
在這裡,我們使用 cy.intercept() 來攔截和模擬 API 請求,該請求根據鍵入的輸入獲取過濾選項。
動態下拉清單通常由 API 呼叫填充,這表示在伺服器回應之前資料不可用。為了處理這些下拉式選單,Cypress 提供了 cy.intercept() 來模擬或攔截網路呼叫。
以下是攔截 API 回應並從動態填入的下拉清單中選擇值的範例:
it('should handle dropdown populated by API', () => { // Intercept the API call cy.intercept('GET', '/api/countries', { fixture: 'countries.json' }).as('getCountries'); cy.get('#load-countries').click(); // Trigger the API call // Wait for the API call to complete cy.wait('@getCountries'); // Now select an option from the populated dropdown cy.get('#country-dropdown').select('Australia'); });
In this case, we use cy.intercept() to mock the /api/countries endpoint and provide a fixture (countries.json) with predefined data. This ensures that the dropdown is populated with the expected values, even in a test environment.
Many modern frameworks (like React, Angular, or Vue) use custom dropdown components that don’t use native
Here’s an example with a custom dropdown built using div and li elements:
<div class="dropdown"> <div class="dropdown-trigger">Select a country</div> <ul class="dropdown-options"> <li>USA</li> <li>Canada</li> <li>Australia</li> </ul> </div>
Here’s how to interact with this type of custom dropdown in Cypress:
it('should select an option from a custom dropdown', () => { cy.get('.dropdown-trigger').click(); // Open the custom dropdown cy.contains('.dropdown-options li', 'Canada').click(); // Select the option });
Use Proper Selectors: Always use specific selectors to avoid flaky tests. Prefer data-* attributes or IDs over generic class selectors.
Handle Delays and Dynamic Content: Cypress automatically waits for elements to appear, but you may still need to use .should() or cy.wait() for AJAX-based dropdowns.
Mock API Responses: Use cy.intercept() to mock API calls when testing dropdowns populated by dynamic data.
Check Dropdown State: Ensure you verify both the closed and open states of the dropdown, especially when dealing with custom components.
Avoid Hard-Coding Delays: Instead of using cy.wait(time), leverage cy.intercept() and cy.wait() for API responses to ensure that tests wait for the actual data rather than arbitrary timeouts.
Handling dynamic dropdowns in Cypress doesn’t have to be complicated. With Cypress’s built-in commands like cy.get(), cy.select(), and cy.intercept(), you can easily interact with both native and custom dropdowns, regardless of whether the content is rendered dynamically. By following best practices and using appropriate selectors and waits, you can make your tests more robust, reliable, and maintainable.
Try out these techniques in your Cypress tests to handle dynamic dropdowns effortlessly!
以上是如何处理 Cypress 中的动态下拉菜单的详细内容。更多信息请关注PHP中文网其他相关文章!