'Page Object Pattern in Cypress?
I want to use a workflow similar to the Page Object Pattern that exists in frameworks like Selenium. I want to use my login.spec.js in my editSettings.spec.js, because it requires a user to be logged in.
How do I achieve this in Cypress? Can I export a function from one test file to use in another?
Solution 1:[1]
I actually came up with these two examples, one using JavaScript and another one with Typescript.
https://github.com/antonyfuentes/cypress-typescript-page-objects https://github.com/antonyfuentes/cypress-javascript-page-objects
Hopefully, this helps someone else.
Solution 2:[2]
Create a SearchProduct.js file in fixtures folder (You can create it anywhere).Then create a class in it and define your all the methods in it something like this:
class ProductPage {
getSearchClick() {
return cy.get('.noo-search');
}
getSearchTextBox(){
return cy.get('.form-control');
}
getProductsName() {
return cy.get('.noo-product-inner h3');
}
getSelectSize() {
return cy.get('#pa_size');
}
getSelectColor() {
return cy.get('#pa_color');
}
getAddtoCartButton() {
return cy.get('.single_add_to_cart_button');
}
}
export default ProductPage
After creating the class, let's import it in the command.js file. After that, let's create a new object of it to access all the methods mentioned above in commands.js.
import ProductPage from '../support/PageObjects/ProductPage';
Cypress.Commands.add("selectProduct", (productName, size , color) => {
// Creating Object for ProductPage
const productPage=new ProductPage();
// Doing the search part for Shirts.
productPage.getSearchClick().click()
productPage.getSearchTextBox().type('Shirt');
productPage.getSearchTextBox().type('{enter}')
productPage.getProductsName().each(($el , index , $list) => {
//cy.log($el.text());
if($el.text().includes(productName)) {
cy.get($el).click();
}
})
// Selecting the size and color and then adding to cart button.
productPage.getSelectColor().select(color);
productPage.getSelectSize().select(size);
productPage.getAddtoCartButton().click();
})
So, here actually the custom command's class is importing and using the Page class. Additionally, the test script will use the same command.js to perform the needed action.
So, the test script will still be the same and will look as below:
// type definitions for Cypress object "cy"
// <reference types="cypress" />
describe('Cypress Page Objects and Custom Commands', function() {
//Mostly used for Setup Part
before(function(){
cy.fixture('example').then(function(data)
{
this.data=data ;
})
})
it('Cypress Test Case', function() {
//Registration on the site
cy.visit('https://shop.demoqa.com/my-account/');
cy.get('#reg_username').type(this.data.Username);
cy.get('#reg_email').type(this.data.Email);
cy.get('#reg_password').type(this.data.NewPassword);
cy.get('.woocommerce-Button').click();
//Checking whether the Registration is successful and whether UserName is populated under login section
cy.get('#username').should('have.value',this.data.Username);
})
// For Loop for Accessing productName array from Features File and Using the custom command
this.data.productName.forEach(function(element){
// Invoke the Custom command selectProduct
cy.selectProduct(element[0],element[1],element[2]);
})
})
You can also directly import the class in Test File by skipping Command.js file.
For that go to the following link:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Antony Fuentes |
| Solution 2 | GHULAM NABI |
