0

I am using Selenium Webdriver on Node.js with Cucumber.js.

I want to run the same test on multiple pages. In this case just checking for 404s in my footer.

My Cucumber .feature file looks like:

Feature: Check footer links
 
    Scenario: Check for broken links in the footer section
        Given I am checking the footer on the '<page>' page
        Then there should be no broken links in the footer on '<page>' page

        Examples: 
        | page        |
        | about-us    |
        | contact-us  |
        | products    |

And in my steps.js file I have:

const { When, Then, Given, AfterAll } = require('@cucumber/cucumber');
const assert = require('assert');
const { Builder, By, until, Key, http } = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');
const XMLHttpRequest = require('xhr2');
var {setDefaultTimeout} = require('@cucumber/cucumber');
setDefaultTimeout(60 * 1000);

Given('I am checking the footers on the {string} page', async function (string) {
    this.driver = new Builder()
        .forBrowser('firefox')
        .build();
    
    this.driver.wait(until.elementLocated(By.className('logo-image')));

    await this.driver.get('https://www.some-site.com/' + string);
});

Then('there should be no broken links in the footer on {string} page', async function(string) {
    var urlArr = [];
    var footerLinks = await this.driver.findElements(By.css('.footer a'));
    for (let i = 0; i < footerLinks.length; i++) {
        var url = await footerLinks[i].getAttribute("href");
        urlArr.push(url);
    }

    if (urlArr.length  < 1) {
        console.log(`Could not find any footer links on ${string} page`);
    }
    else {
        for (let i = 0; i < urlArr.length; i++) {
            var respStatus = await checkLink(urlArr[i]);
            assert.ok(respStatus==200);
        }
    }
});


function checkLink(url) {
   //Check link function returns status code....
}

This works fine, but for one thing: For each page that is tested a new instance of FireFox opens up.

I tried adding

After(async function() {
    this.driver.quit();
});

To the end but this closes the session completely and the other tests fail after the first initial one is done.

Would anyone know how I could repeat the tests in the same browser instance?

1 Answer 1

1

You can create a wrapper for your driver, so you can control when the driver object is created and closed.

// features/support/world.js

const { setWorldConstructor } = require('@cucumber/cucumber');
const { Builder } = require('selenium-webdriver');

class CustomWorld {
  constructor() {
    this.driver = new Builder().forBrowser('chrome').build();
  }

  async quit() {
    await this.driver.quit();
  }
}

setWorldConstructor(CustomWorld);

Here, quit() is called only when the CustomerWorld object is destroyed. setWorldConstructor will make the driver available in the step definitions using this.driver.

You can configure to use this world file like this

// cucumber.js
{
  "default": {
    "require": [
      "features/support/world.js",
      "features/step-definitions/*.js"
    ],
    "format": ["pretty"]
  }
}
4
  • Thanks! Dumb question, but how then do I implement this file? Will it just pick up and run whenever I run a test or do I have to reference it in every test file?
    – MeltingDog
    Commented May 16 at 23:10
  • 1
    @MeltingDog I have added how to configure the world file. "Will it just pick up and run whenever I run a test or do I have to reference it in every test file?" If configured as showed, it will be taken by Cucumber - no need to reference it on the step defintinions. Commented May 17 at 7:48
  • @MeltingDog If the answer is satisfactory, can you mark it as accepted? It will show others the answer resolves the problem. Commented May 17 at 7:49
  • Thanks for this, but I am still a bit confused. Where do I place the cucmber.js file? And how do I modify my steps.js code above to use the world. I cannot seem to find any information on how to implement this on Google. Do you know of any tutorial pages?
    – MeltingDog
    Commented May 22 at 0:41

Your Answer

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

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