I’m presenting you with my recent Cypress test automation project, which I have been working on for the last few days. I came up with an idea to cover a part of the testing procedure that is currently done only manually in our company.
The Challenge
The Replacement Matrix phase involves updating numerous products, ensuring their replacements are correctly mapped, and verifying that all related products are accurate. Manually performing these tasks is not only tedious but also prone to human error. Given the high volume of products and the critical nature of accurate replacements, there was a pressing need for an automated solution to streamline the process.
Manual or Automated testing?
Currently, the entire procedure of managing the Replacement Matrix in our SAP Hybris system is handled manually. It involves painstaking steps that are time-consuming and susceptible to human error. Each product and its related replacements must be meticulously updated and verified by hand, demanding significant resources and attention to detail.
However, the updates I am presenting today promise a transformative change. By integrating Cypress automation into this process, we can shift from a labor-intensive manual approach to an efficient, automated system. This automation will not only streamline the workflow, reducing the time required to complete these tasks, but it will also enhance accuracy and reliability, minimizing the potential for errors that could disrupt our operations.
Consequently, these updates mark a significant step forward in optimizing our procedures, freeing up valuable human resources, and ensuring that our Replacement Matrix is managed with the highest level of precision and efficiency.
An example of a Replacement Matrix template:
Here is an example of a template that we use to update eligible replacement products. In the C column, we find the base product name; in the D column, we find its code. In columns F and G, as well as in columns H and J, we find eligible replacement products for that base product.
As you will see in the prototype code, I have set a search for the base product and, inside of it, in the Category tab, set Cypress to search for the product codes from columns D (eligible for replacement with itself) F and H. If test results are passed, it means that all these product codes and the products were successfully obtainable for replacement.
Passing comment
I’ve consulted some experts in the field of test automation via StackOverflow, to see their opinions and suggestions related to this type of testing. Some of them suggested me to go for Playwright instead:
Kiowa said: Cypress is not so good with sophisticated frameworks like SAP, it tends to get confused when the page refreshes. You may find Playwright gives better results.
From what I can see, they are probably right. But still, our company uses Cypress for testing. Introducing another testing tool would be too time and resource-consuming for us at this moment. That is why I’ve given my best to get solutions through Cypress. The code I’m presenting below works without blockers, proving that Cypress can still handle tasks in sophisticated platforms such as SAP Hybris.
The Prototype code
Here is the code that I’m presenting as a prototype. I’ve tested it multiple times, and it works just fine. I’ve included enough .wait() commands so Hybris can process every step correctly without encountering tedious errors. From my experience with Hybris, it seems that proper timing between each command/action appears to be key in order to get a well-functioning test.
Of course, I don’t doubt that this initial code will be updated in the future, so I will definitely update this article with those changes after they are tested.
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from
// failing the test
return false
})
describe('Replacement Matrix test', () => {
it('Check if all requested products are listed for replacement', () => {
// Visit the page where the input element is located
cy.visit('https://backoffice.stg.iqos.com/backoffice/login.zul', { failOnStatusCode: false });
//LOGIN - Insert your Username and Password
cy.get('input[placeholder="Enter user name"]:visible').type("Type your username");
cy.get('input[placeholder="Enter password"]:visible').type("Type your password");
//You should end up on the Products page after this
cy.get('.login_btn').click()
.wait(30000);
cy.get('.yw-selector-btn').click()
.wait(20000);
cy.get('span.z-label')
.contains("Products")
.click()
.wait(300);
//Product 1
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('.z-bandbox-input').eq(3).should('be.visible').type("G0000605",{ force: true }).wait(300);
cy.get('.yw-fulltextsearch-search-button').eq(0).click().wait(300);
cy.get('span.yw-coll-browser-hyperlink').contains("[] - IQOS ILUMA One Holder Sunset Red [G0000605] - Tunisia Product Catalog : Staged").scrollIntoView().should('be.visible').click({force:true});
cy.wait(5000)
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
// Check products listed for replacement by products codes
cy.get('.z-listitem')
.contains("G0000605");
cy.get('.z-listitem')
.contains("G0000607");
cy.get('.z-listitem')
.contains("G0000608");
cy.get('.z-listitem')
.contains("G0000604");
cy.get('.z-listitem')
.contains("G0000592");
//Product 2
cy.get('.yw-navigationhistory-back').eq(0).should('be.visible').click({ force: true });
cy.get('button[title="Clear"]').eq(0).click().wait(1000);
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('.z-bandbox-input').eq(5).click().type("G0000606").wait(1000);
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('span.yw-coll-browser-hyperlink').contains("[] - IQOS ILUMA One Holder Pebbe Grey [G0000606] - Tunisia Product Catalog : Staged").scrollIntoView().should('be.visible').click({force:true});
cy.wait(5000)
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
// Check products listed for replacement by products codes
cy.get('.z-listitem')
.contains("G0000605");
cy.get('.z-listitem')
.contains("G0000607");
cy.get('.z-listitem')
.contains("G0000608");
cy.get('.z-listitem')
.contains("G0000604");
cy.get('.z-listitem')
.contains("G0000592");
//Product 3
cy.get('.yw-navigationhistory-back').eq(0).should('be.visible').click({ force: true });
cy.get('button[title="Clear"]').eq(0).click().wait(1000);
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('.z-bandbox-input').eq(5).click().type("G0000607").wait(1000);
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('span.yw-coll-browser-hyperlink').contains("[] - IQOS ILUMA One Holder Moss Green [G0000607] - Tunisia Product Catalog : Staged").scrollIntoView().should('be.visible').click({force:true});
cy.wait(5000)
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
// Check products listed for replacement by products codes
cy.get('.z-listitem')
.contains("G0000605");
cy.get('.z-listitem')
.contains("G0000607");
cy.get('.z-listitem')
.contains("G0000608");
cy.get('.z-listitem')
.contains("G0000604");
cy.get('.z-listitem')
.contains("G0000593");
//Product 4
cy.get('.yw-navigationhistory-back').eq(0).should('be.visible').click({ force: true });
cy.get('button[title="Clear"]').eq(0).click().wait(1000);
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('.z-bandbox-input').eq(5).click().type("G0000625").wait(1000);
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('span.yw-coll-browser-hyperlink').contains("[] - IQOS ILUMA Charger Azure Blue [G0000625] - Tunisia Product Catalog : Staged").scrollIntoView().should('be.visible').click({force:true});
cy.wait(5000)
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
// Check products listed for replacement by products codes
cy.get('.z-listitem')
.contains("G0000622");
cy.get('.z-listitem')
.contains("G0000623");
cy.get('.z-listitem')
.contains("G0000624");
cy.get('.z-listitem')
.contains("G0000626");
cy.get('.z-listitem')
.contains("G0000600");
cy.get('.z-listitem')
.contains("G0000601");
cy.get('.z-listitem')
.contains("G0000602");
cy.get('.z-listitem')
.contains("G0000603");
cy.get('.z-listitem')
.contains("G0000599");
});
});
Detailed Explanation of the Code
Handling Uncaught Exceptions
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from failing the test
return false;
});
In Cypress, unhandled exceptions can cause tests to fail unexpectedly. This line of code is a global exception handler that listens for any uncaught exceptions that may occur during the test execution. The return false
This statement tells Cypress to ignore these exceptions, ensuring that the test does not fail due to unexpected errors outside the scope of what is being tested. This is particularly useful for dealing with issues caused by the application under test that do not necessarily indicate a failure of the test itself.
Describing the Test Suite
describe('Replacement Matrix test', () => {
it('Check if all requested products are listed for replacement', () => {
The describe
block is used to define a test suite, grouping related tests together. In this case, the test suite is named “Replacement Matrix test”. Inside this block, the it
function defines an individual test case named “Check if all requested products are listed for replacement”. This test case contains all the steps needed to verify that the correct replacement products are listed for specific base products.
Visiting the Login Page
cy.visit('https://backoffice.stg.iqos.com/backoffice/login.zul', { failOnStatusCode: false });
This line tells Cypress to navigate to the specified URL, which is the login page for the application. The { failOnStatusCode: false }
option instructs Cypress to continue running the test even if the server responds with a status code indicating an error, such as 404 or 500.
Logging In
cy.get('input[placeholder="Enter user name"]:visible').type("Type your username
");
cy.get('input[placeholder="Enter password"]:visible').type("Type your password
");
cy.get('.login_btn').click().wait(30000);
These lines automate the login process:
cy.get('input[placeholder="Enter user name"]:visible').type("Type your username")
: Finds the username input field by its placeholder text and types the username.cy.get('input[placeholder="Enter password"]:visible').type("Type your password!")
: Finds the password input field by its placeholder text and types the password.cy.get('.login_btn').click().wait(30000)
: Clicks the login button and waits for 30 seconds to ensure the login process completes and the subsequent page fully loads.
Navigating to the Products Page
cy.get('.yw-selector-btn').click().wait(20000);
cy.get('span.z-label').contains("Products").click().wait(300);
After logging in, these lines navigate to the Products page:
cy.get('.yw-selector-btn').click().wait(20000)
: Clicks a selector button and waits for 20 seconds for the resulting page or modal to load.cy.get('span.z-label').contains("Products").click().wait(300)
: Finds and clicks the “Products” link or button, waiting an additional 300 milliseconds to ensure it is loaded.
Searching and Validating Products
The script then proceeds to search for and validate specific products. Here’s how it handles each product:
Initial Product / Product 1
//Product 1
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('.z-bandbox-input').eq(3).should('be.visible').type("G0000605",{ force: true }).wait(300);
cy.get('.yw-fulltextsearch-search-button').eq(0).click().wait(300);
cy.get('span.yw-coll-browser-hyperlink').contains("[] - IQOS ILUMA One Holder Sunset Red [G0000605] - Tunisia Product Catalog : Staged").scrollIntoView().should('be.visible').click({force:true});
cy.wait(5000)
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
// Check products listed for replacement by products codes
cy.get('.z-listitem').contains("G0000605");
cy.get('.z-listitem').contains("G0000607");
cy.get('.z-listitem').contains("G0000608");
cy.get('.z-listitem').contains("G0000604");
cy.get('.z-listitem').contains("G0000592");
- The search button is clicked to open the search input.
- The product code “G0000605” is typed into the input field.
- The search button is clicked again to initiate the search.
- The script waits for the product link to be visible, scrolls into view, and clicks it.
- After waiting for the product details to load, the script navigates to the “Categories” tab.
- It then checks that the listed products for replacement include the expected product codes.
Difference Between Product 1 and Product 2 Sections (other sections)
Product 1 Section
The first product section in the script performs the following steps:
Initiate Search:
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
Type Product Code:
cy.get('.z-bandbox-input').eq(3).should('be.visible').type("G0000605", { force: true }).wait(300);
Perform Search:
cy.get('.yw-fulltextsearch-search-button').eq(0).click().wait(300);
Select Product:
cy.get('span.yw-coll-browser-hyperlink').contains("[] - IQOS ILUMA One Holder Sunset Red [G0000605] - Tunisia Product Catalog : Staged").scrollIntoView().should('be.visible').click({ force: true });
Wait for Product Details to Load:
cy.wait(5000);
Navigate to Categories Tab:
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
Validate Replacement Products:
cy.get('.z-listitem').contains("G0000605");
cy.get('.z-listitem').contains("G0000607");
cy.get('.z-listitem').contains("G0000608");
cy.get('.z-listitem').contains("G0000604");
cy.get('.z-listitem').contains("G0000592");
Product 2 Section
The second product section modifies the steps slightly to optimize the process:
Navigate Back to the Previous Page:
cy.get('.yw-navigationhistory-back').eq(0).should('be.visible').click({ force: true });
Clear Previous Search:
cy.get('button[title="Clear"]').eq(0).click().wait(1000);
Initiate Search:
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
Type Product Code:
cy.get('.z-bandbox-input').eq(5).click().type("G0000606").wait(1000);
Perform Search:
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
Select Product:
cy.get('span.yw-coll-browser-hyperlink').contains("[] - IQOS ILUMA One Holder Pebbe Grey [G0000606] - Tunisia Product Catalog : Staged").scrollIntoView().should('be.visible').click({ force: true });
Wait for Product Details to Load:
cy.wait(5000);
Navigate to Categories Tab:
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
Validate Replacement Products:
cy.get('.z-listitem').contains("G0000605");
cy.get('.z-listitem').contains("G0000607");
cy.get('.z-listitem').contains("G0000608");
cy.get('.z-listitem').contains("G0000604");
cy.get('.z-listitem').contains("G0000592");
Differences
- Navigation Handling:
- Product 1: Directly initiates the search from a fresh state.
- Product 2: Uses navigation history to return to the previous page and clear the search input before starting a new search.
- Search Input Field Index:
- Product 1: Uses
cy.get('.z-bandbox-input').eq(3)
for typing the product code. - Product 2: Uses
cy.get('.z-bandbox-input').eq(5)
for typing the product code, which might indicate a different element index due to the page state after navigating back.
- Product 1: Uses
Scheme for Other Products
All other product sections (3, 4, 5, …) should be based on the scheme used in the Product 2 section. This involves:
- Navigating back to the previous page (Products page).
- Clearing any previous search input.
- Initiating a new search.
- Typing the product code in the search input field.
- Performing the search.
- Selecting the desired product from the search results.
- Waiting for the product details to load.
- Navigating to the “Categories” tab.
- Validating the replacement products listed.
By following this scheme, the script ensures consistency and reliability in the testing process, especially when dealing with multiple product validations.
Updated code (testing replacement product level)
I’ve tested the initial code with my colleagues from the product management team. They asked if I could include in the script testing of the replacement product level. I’ve come up with the following solution:
Namely, since the levels are mentioned in each replacement product title, then I’ve just included those as additional queries along with the codes. An example of an updated command now looks like this:
cy.get('.z-listitem')
.contains("G0000592")
.should('contain', 'CAN_BE_REPLACED_BY_2L ->');
Instructions for checking the product replacement level:
//Level 1 products: .should(‘contain’, ‘CAN_BE_REPLACED_BY ->’)
//Level 2 products: .should(‘contain’, ‘CAN_BE_REPLACED_BY_2L ->’)
//Level 3 products: .should(‘contain’, ‘CAN_BE_REPLACED_BY_3L ->’)
Also, I’ve updated this part of the code, where Cypress searches for the products listed on the Products page that match the market (and environment).
cy.get('span.yw-coll-browser-hyperlink').contains("Tunisia Product Catalog : Staged").scrollIntoView().should('be.visible').click({force:true});
Instead of using the whole title as the contains query (as in the initial code), I’ve only included the part containing the market and the environment. This way, we don’t have to use a particular title to search for each product; we are using a universal selector for the whole market (Tunisia, in this case).
The new code:
You may find the updated parts in the code bolded.
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from
// failing the test
return false
})
describe('Replacement Matrix test', () => {
it('Check if all requested products are listed for replacement', () => {
// Visit the page where the input element is located
cy.visit('https://backoffice.stg.iqos.com/backoffice/login.zul', { failOnStatusCode: false });
//LOGIN - Insert your Username and Password
cy.get('input[placeholder="Enter user name"]:visible').type("Type your username");
cy.get('input[placeholder="Enter password"]:visible').type("Type your password");
//You should end up on the Products page after this
cy.get('.login_btn').click()
.wait(30000);
cy.get('.yw-selector-btn').click()
.wait(20000);
cy.get('span.z-label')
.contains("Products")
.click()
.wait(300);
//Instructions for checking the product replacement level:
//Level 1 products: .should('contain', 'CAN_BE_REPLACED_BY ->')
//Level 2 products: .should('contain', 'CAN_BE_REPLACED_BY_2L ->')
//Level 3 products: .should('contain', 'CAN_BE_REPLACED_BY_3L ->')
//Product 1
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('.z-bandbox-input').eq(3).should('be.visible').type("G0000605",{ force: true }).wait(300);
cy.get('.yw-fulltextsearch-search-button').eq(0).click().wait(300);
cy.get('span.yw-coll-browser-hyperlink').contains("Tunisia Product Catalog : Staged").scrollIntoView().should('be.visible').click({force:true});
cy.wait(5000)
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
// Check products listed for replacement by products codes
cy.get('.z-listitem')
.contains("G0000605")
.should('contain', 'CAN_BE_REPLACED_BY ->');
cy.get('.z-listitem')
.contains("G0000607")
.should('contain', 'CAN_BE_REPLACED_BY ->');
cy.get('.z-listitem')
.contains("G0000608")
.should('contain', 'CAN_BE_REPLACED_BY ->');
cy.get('.z-listitem')
.contains("G0000604")
.should('contain', 'CAN_BE_REPLACED_BY ->');
cy.get('.z-listitem')
.contains("G0000592")
.should('contain', 'CAN_BE_REPLACED_BY_2L ->');
//Product 2
cy.get('.yw-navigationhistory-back').eq(0).should('be.visible').click({ force: true });
cy.get('button[title="Clear"]').eq(0).click().wait(1000);
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('.z-bandbox-input').eq(5).click().type("G0000606").wait(1000);
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('span.yw-coll-browser-hyperlink').contains("Tunisia Product Catalog : Staged").scrollIntoView().should('be.visible').click({force:true});
cy.wait(5000)
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
// Check products listed for replacement by products codes
cy.get('.z-listitem')
.contains("G0000606")
.should('contain', 'CAN_BE_REPLACED_BY ->');
cy.get('.z-listitem')
.contains("G0000607")
.should('contain', 'CAN_BE_REPLACED_BY_2L ->');
cy.get('.z-listitem')
.contains("G0000608")
.should('contain', 'CAN_BE_REPLACED_BY_2L ->');
cy.get('.z-listitem')
.contains("G0000604")
.should('contain', 'CAN_BE_REPLACED_BY_2L ->');
cy.get('.z-listitem')
.contains("G0000592")
.should('contain', 'CAN_BE_REPLACED_BY_3L ->');
//Product 3
cy.get('.yw-navigationhistory-back').eq(0).should('be.visible').click({ force: true });
cy.get('button[title="Clear"]').eq(0).click().wait(1000);
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('.z-bandbox-input').eq(5).click().type("G0000607").wait(1000);
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('span.yw-coll-browser-hyperlink').contains("Tunisia Product Catalog : Staged").scrollIntoView().should('be.visible').click({force:true});
cy.wait(5000)
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
// Check products listed for replacement by products codes
cy.get('.z-listitem')
.contains("G0000605")
.should('contain', 'CAN_BE_REPLACED_BY_2L ->');
cy.get('.z-listitem')
.contains("G0000607")
.should('contain', 'CAN_BE_REPLACED_BY ->');
cy.get('.z-listitem')
.contains("G0000608")
.should('contain', 'CAN_BE_REPLACED_BY_2L ->');
cy.get('.z-listitem')
.contains("G0000604")
.should('contain', 'CAN_BE_REPLACED_BY_2L ->');
cy.get('.z-listitem')
.contains("G0000593")
.should('contain', 'CAN_BE_REPLACED_BY_3L ->');
//Product 4
cy.get('.yw-navigationhistory-back').eq(0).should('be.visible').click({ force: true });
cy.get('button[title="Clear"]').eq(0).click().wait(1000);
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('.z-bandbox-input').eq(5).click().type("G0000625").wait(1000);
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
cy.get('span.yw-coll-browser-hyperlink').contains("Tunisia Product Catalog : Staged").scrollIntoView().should('be.visible').click({force:true});
cy.wait(5000)
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
// Check products listed for replacement by products codes
cy.get('.z-listitem')
.contains("G0000622")
.should('contain', 'CAN_BE_REPLACED_BY_2L ->');
cy.get('.z-listitem')
.contains("G0000623")
.should('contain', 'CAN_BE_REPLACED_BY_2L ->');
cy.get('.z-listitem')
.contains("G0000624")
.should('contain', 'CAN_BE_REPLACED_BY_2L ->');
cy.get('.z-listitem')
.contains("G0000626")
.should('contain', 'CAN_BE_REPLACED_BY_2L ->');
cy.get('.z-listitem')
.contains("G0000600")
.should('contain', 'CAN_BE_REPLACED_BY_3L ->');
cy.get('.z-listitem')
.contains("G0000601")
.should('contain', 'CAN_BE_REPLACED_BY_3L ->');
cy.get('.z-listitem')
.contains("G0000602")
.should('contain', 'CAN_BE_REPLACED_BY_3L ->');
cy.get('.z-listitem')
.contains("G0000599")
.should('contain', 'CAN_BE_REPLACED_BY_3L ->');
});
});
Update 2 (Extract Common Steps into Reusable Functions)
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from failing the test
return false;
});
describe('Replacement Matrix test', () => {
const CATALOG_LABEL = 'Tunisia Product Catalog : Staged';
beforeEach(() => {
// Visit the login page before each test
cy.visit('https://backoffice.stg.iqos.com/backoffice/login.zul', { failOnStatusCode: false }).wait(1000);
// Log in to the application
cy.get('input[placeholder="Enter user name"]:visible').type("type your username").wait(300);
cy.get('input[placeholder="Enter password"]:visible').type("type your password");
cy.get('.login_btn').click({ force: true }).wait(30000);
// Wait for the main page to load and Products button to be visible
cy.get('.yw-selector-btn').click().wait(20000);
cy.get('span.z-label').contains("Products").click().wait(300);
});
const LABELS = {
L1: 'CAN_BE_REPLACED_BY ->',
L2: 'CAN_BE_REPLACED_BY_2L ->',
L3: 'CAN_BE_REPLACED_BY_3L ->'
};
const checkProductReplacements = (productCode, replacements, isFirstSearch) => {
cy.get('.yw-fulltextsearch-search-button').eq(0).click();
// Determine the correct input element to type into based on whether it's the first search
const inputIndex = isFirstSearch ? 3 : 5;
cy.get('.z-bandbox-input').eq(inputIndex).type(productCode, { force: true }).wait(300);
cy.get('.yw-fulltextsearch-search-button').eq(0).click().wait(300);
cy.get('span.yw-coll-browser-hyperlink').contains(CATALOG_LABEL).scrollIntoView().should('be.visible').click({ force: true });
cy.wait(5000);
cy.get('.yw-editorarea-tabbox-tabs-tab').contains("Categories").click().wait(300);
replacements.forEach(replacement => {
const label = LABELS[replacement.level];
cy.get('.z-listitem')
.contains(replacement.code)
.should('contain', label)
.parent()
.should('contain', CATALOG_LABEL);
});
// Go back to the search page
cy.get('.yw-navigationhistory-back').eq(0).should('be.visible').click({ force: true });
cy.get('button[title="Clear"]').eq(0).click().wait(1000);
};
// Search for the main product code and check the replacement product codes and levels
it('Check if all requested products are listed for replacement', () => {
checkProductReplacements("G0000605", [
{ code: "G0000605", level: 'L1' },
{ code: "G0000607", level: 'L1' },
{ code: "G0000608", level: 'L1' },
{ code: "G0000604", level: 'L1' },
{ code: "G0000592", level: 'L2' }
], true);
checkProductReplacements("G0000606", [
{ code: "G0000606", level: 'L1' },
{ code: "G0000607", level: 'L2' },
{ code: "G0000608", level: 'L2' },
{ code: "G0000604", level: 'L2' },
{ code: "G0000592", level: 'L3' }
], false);
checkProductReplacements("G0000607", [
{ code: "G0000605", level: 'L2' },
{ code: "G0000607", level: 'L1' },
{ code: "G0000608", level: 'L2' },
{ code: "G0000604", level: 'L2' },
{ code: "G0000593", level: 'L3' }
], false);
checkProductReplacements("G0000625", [
{ code: "G0000622", level: 'L2' },
{ code: "G0000623", level: 'L2' },
{ code: "G0000624", level: 'L2' },
{ code: "G0000626", level: 'L2' },
{ code: "G0000600", level: 'L3' },
{ code: "G0000601", level: 'L3' },
{ code: "G0000602", level: 'L3' },
{ code: "G0000599", level: 'L3' }
], false);
});
});
Constants and Variables
const CATALOG_LABEL = 'Tunisia Product Catalog : Staged';
const LABELS = {
L1: 'CAN_BE_REPLACED_BY ->',
L2: 'CAN_BE_REPLACED_BY_2L ->',
L3: 'CAN_BE_REPLACED_BY_3L ->'
};
- Purpose: Defines constants and variables used throughout the test suite.
- Explanation:
CATALOG_LABEL
: Stores the label for the product catalog ('Tunisia Product Catalog : Staged'
). This label is used later in test assertions.LABELS
: Stores replacement level labels ('L1'
,'L2'
,'L3'
) mapped to their respective values ('CAN_BE_REPLACED_BY ->'
,'CAN_BE_REPLACED_BY_2L ->'
,'CAN_BE_REPLACED_BY_3L ->'
). These labels are used to verify the replacement level of products.
checkProductReplacements
Function
const checkProductReplacements = (productCode, replacements, isFirstSearch) => {
// Function body
};
- Purpose: Defines a reusable function to perform checks on product replacements.
- Explanation:
- Parameters:
productCode
: The main product code to search for.replacements
: An array of replacement objects, each containingcode
andlevel
properties.isFirstSearch
: Boolean indicating whether it’s the first search.
- Functionality:
- Initiates a product search based on
productCode
. - Scrolls and clicks on the specified product catalog link (
'span.yw-coll-browser-hyperlink'
). - Waits for the page to load and selects the “Categories” tab (
'.yw-editorarea-tabbox-tabs-tab'
). - Iterates through each replacement object to verify:
- The presence of the correct
LABELS[replacement.level]
. - The presence of
CATALOG_LABEL
.
- The presence of the correct
- Navigates back to the search page after completing the checks.
- Initiates a product search based on
- Parameters:
Test Cases
it('Check if all requested products are listed for replacement', () => {
// Test cases utilizing checkProductReplacements function
});
- Purpose: Defines individual test cases within the test suite.
- Explanation:
it
Function: Represents an individual test case or specification.- Test Case: Each test case calls the
checkProductReplacements
function with different parameters (productCode
,replacements
,isFirstSearch
). - Assertions: Each call verifies if the requested products are listed for replacement based on predefined expectations (
LABELS
andCATALOG_LABEL
).
Summary
This Cypress test suite is structured to verify the replacement matrix functionality of a web application. It includes setup steps (login, navigation), defines constants for labels, implements a reusable function for verification, and contains multiple test cases to validate different scenarios of product replacement levels. Each test case ensures that the expected products are correctly listed with their respective replacement levels and catalog labels.