How to create and call selectors from a separate file in Cypress?

Viewed 1198

I am new to Cypress and struggling to get it work. I need to create a file with selectors (I suppose in 'support' folder) to use them in my project file.

Here is an example

describe('Test_spec_1', () => {
 it.only('Visits the site & verifies elements', () => {
  cy.get('[type=text]').should('be.visible')
  cy.get('[type=password]').should('be.visible') 
  cy.get('[type=submit]').should('be.visible')
  cy.get('[routerlink="/login"]').should('be.visible')
  cy.get('[routerlink="/reset-password"]').should('be.visible')
  cy.get('[routerlink="/support"]').should('be.visible')
  cy.get('[routerlink="/reset-password"]').should('be.visible')
 })
})

Basically, I need to have all selectors in a separate file, so I can call them and update their values easily. I have experimented a bit with export/import, but it did not work. Could't find anywhere how to use it properly. It would be great if you can give me some hints how to do it. Thank you very much.

2 Answers

You can create a folder called page-objects inside your integration folder. Inside that you can create one js file for each screen like login.js. Now inside that you can write your locators like:

class login {
    usernameInput() {
        return cy.get('[type=text]')
    }
    passwordInput() {
        return cy.get('[type=password]')
    }
    submitButton() {
        return cy.get('[type=submit]')
    }
}
export default login

Inside your tests you can use them as:

import login from '/page-objects/login.js'
const loginPage = new login();

describe('Test_spec_1', function() {
    it('Visits the site & verifies elements', function() {
        loginPage.usernameInput().should('be.visible')
        loginPage.passwordInput().should('be.visible')
        loginPage.submitButton().should('be.visible')
    })
})

Please don't use page objects in Cypress, see this tutorial Stop using Page Objects

Page objects problems

  1. Page objects are hard to maintain and take away time from actual application development. I have never seen PageObjects documented well enough to actually help one write tests.

  2. Page objects introduce additional state into the tests, which is separate from the application’s internal state. This makes understanding the tests and failures harder.

  3. Page objects try to fit multiple cases into a uniform interface, falling back to conditional logic - a huge anti-pattern in our opinion.

  4. Page objects make tests slow because they force the tests to always go through the application user interface.

Number 3) killed it for me. You get to a point where you try to figure out more convoluted methods in the page object to cater for different scenarios.


The easiest way to store your selector text in one place is given in this question Where to store selectors in Cypress.io

// cypress/support/selectors.js

export default {
  mySelector: '.my-selector',
  mySelector2: '.my-selector-2'
};
// cypress/integration/one.spec.js

import selectors from '../support/selectors.js';

describe('test', () => {
  it('test', () => {
    cy.get(selectors.mySelector);
  });
});
Related