0

Writing end2end tests with Cypress and cucumber, on a high level the test cases are as following:

Feature: Users can change color scheme

  @focus
  Scenario: The user changes color scheme from Black to white (default) to Grey on light grey
    Given The user clicks the Start button
    When The user clicks the accessibility button
    And The user clicks the Grey on light grey radio button
    And The user clicks OK
    Then The color scheme changes to Grey on light grey

  @focus
  Scenario: The user changes color scheme from Black to white (default) to Purple on light green
    When The user clicks the accessibility button
    And The user clicks the Purple on light green radio button
    And The user clicks OK
    Then The color scheme changes to Purple on light green

  @focus
  Scenario: The user changes color scheme from Black to white (default) to Black on violet
    When The user clicks the accessibility button
    And The user clicks the Black on violet radio button
    And The user clicks OK
    Then The color scheme changes to Black on violet

  @focus
  Scenario: The user changes color scheme from Black to white (default) to Yellow on navy
    When The user clicks the accessibility button
    And The user clicks the Yellow on navy radio button
    And The user clicks OK
    Then The color scheme changes to Yellow on navy

  @focus
  Scenario: The user changes color scheme from Black to white (default) to White on black
    When The user clicks the accessibility button
    And The user clicks the White on black radio button
    And The user clicks OK
    Then The color scheme changes to White on black

As we can see, for each test scenario, there are at least identical steps:

When The user clicks the accessibility button
And The user clicks OK

How the testing steps are implemented are:

// Common ==================================================  
When('The user clicks the accessibility button', () => {
    cy.get(selectors.buttons.sideMenu.accessibility)
    .click();
});

And('The user clicks OK', () => {
    cy.contains(selectors.accessibilityOptions.okButton)
    .click();
});

// Grey on light grey ==================================================
Given('The user clicks the Start button', () => {
    cy.get(selectors.buttons.startTest)
    .click();
});

And('The user clicks the Grey on light grey radio button', () => {
    cy.contains(selectors.accessibilityOptions.colorScheme.greyOnLightGrey)
    .click();
});

Then('The color scheme changes to Grey on light grey', () => {
    cy.get(selectors.buttons.sideMenu.accessibility)
    .should('have.css', 'background-color', lightGrey);
    cy.get(selectors.buttons.sideMenu.accessibility)
    .should('have.css', 'border-bottom-color', grey);
});

// Purple on light green ==================================================
And('The user clicks the Purple on light green radio button', () => {
    cy.contains(selectors.accessibilityOptions.colorScheme.purpleOnLightGreen)
    .click();
});

Then('The color scheme changes to Purple on light green', () => {
    cy.get(selectors.buttons.sideMenu.accessibility)
    .should('have.css', 'background-color', lightGreen);
    cy.get(selectors.buttons.sideMenu.accessibility)
    .should('have.css', 'border-bottom-color', purple);
});

// Black on violet ==================================================
And('The user clicks the Black on violet radio button', () => {
    cy.contains(selectors.accessibilityOptions.colorScheme.blackOnViolet)
    .click();
});

Then('The color scheme changes to Black on violet', () => {
    cy.get(selectors.buttons.sideMenu.accessibility)
    .should('have.css', 'background-color', violet);
    cy.get(selectors.buttons.sideMenu.accessibility)
    .should('have.css', 'border-bottom-color', lightBlack);
});

// Yellow on navy ==================================================
And('The user clicks the Yellow on navy radio button', () => {
    cy.contains(selectors.accessibilityOptions.colorScheme.yellowOnNavy)
    .click();
});

Then('The color scheme changes to Yellow on navy', () => {
    cy.get(selectors.buttons.sideMenu.accessibility)
    .should('have.css', 'background-color', navy);
    cy.get(selectors.buttons.sideMenu.accessibility)
    .should('have.css', 'border-bottom-color', yellow);
});

// White on black ==================================================
And('The user clicks the White on black radio button', () => {
    cy.contains(selectors.accessibilityOptions.colorScheme.whiteOnBlack)
    .click();
});

Then('The color scheme changes to White on black', () => {
    cy.get(selectors.buttons.sideMenu.accessibility)
    .should('have.css', 'background-color', white);
    cy.get(selectors.buttons.sideMenu.accessibility)
    .should('have.css', 'border-bottom-color', blackRGB);
});

In implementation, I extracted repeated steps to the top instead of repeating them for every test scenario. But the problem is: the testing steps are now out of order. This may present a problem during future maintenance.

I personally think there should be a more elegant solution. Any suggestions?

1
  • You have only one Given in the 1st test, is it because the tests have to be executed in order and they all depend on successful execution of the 1st test? I'd also use passive past tense for Given and passive future simple tense for Then, which might be a detail but it helps in figuring out what pre-conditions and actions are, and what you test for.
    – pavelsaman
    Jul 26, 2020 at 8:57

1 Answer 1

1

It looks like for the internal implementation, you need to extract delegate function, that would perform these actions in a following order:

cy.get(selectors.buttons.sideMenu.accessibility).click();
function();
cy.contains(selectors.accessibilityOptions.okButton).click();

In C# this mechanism is called delegates, for JS - you need to implement a callback function(I might be mistaken), that would accept function.

In this pseudocode example - function() is the function that clicks on the particular color radio button e.g.

And The user clicks the Purple on light green radio button

See examples: https://developer.mozilla.org/en-US/docs/Glossary/Callback_function https://javascript.info/callbacks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.