0

Here is a sample code which am using for selenium WebDriver JS axe integration to test my website for accessibility -

var AxeBuilder = require('axe-webdriverjs');
var WebDriver = require('selenium-webdriver');

var driver = new WebDriver.Builder()
  .forBrowser('firefox')
  .build();

driver
  .get('https://dequeuniversity.com/demo/mars/')
  .then(function() {
    AxeBuilder(driver).analyze(function(err, results) {
      if (err) {
        // Handle error somehow
      }
      console.log(results);
    });
  });

There is one URL that is being parsed here. Can someone help me with how I can parse multiple urls? I would want the print the results of all the urls being given as input to driver.get(). Any help would be appreciated !

Reference - https://github.com/dequelabs/axe-webdriverjs

1
  • 3
    await each Promise or use Promise.all? Commented Dec 18, 2018 at 1:15

3 Answers 3

1

Use Promise.all and map a url array.

const urlArray = [url1,url2,url3,...];
const finalResult = await Promise.all(urlArray.map(async url=>{
   return await driver.get(url);
}))

you will get all the result in the array finalResult.

Sign up to request clarification or add additional context in comments.

Comments

1

So I'll format the @CertainPerformance's comment as an answer.

The simplest approach is using the modern async/await syntax:

for (const url of [url1, url2, url3]) {
    await driver
      .get(url)
      .then(async function() {
        await AxeBuilder(driver).analyze(function(err, results) {
          if (err) {
            // Handle error somehow
          }
          console.log(results);
        });
      });
}

Do not forget to replace url1, url2, url3 with your urls.

P.S. as @jfriend00 stated (in comments below), we don't know if AxeBuilder function is actually returns a promise or not. So the await before it (and async) may be unnecessary in the latter case.

7 Comments

This won't wait for AxeBuilder().analyze() to finish before going onto the next iteration of the loop.
@jfriend00 Missed that, fixed!
I don't know this library, but its unlikely that .analyze() returns a promise and takes a callback. If it doesn't return a promise, await won't do anything useful.
@jfriend00 Yep, added a postscriptum.
You still don't show a solution that would actually wait for all async things to be done before iterating the loop.
|
1

the above solution will work, but it will be serialized i.e. you will get the result of the driver.get promise and then analyze the result of one url before moving to the next. maybe you could use promise.all to do it all in parallel. Something on the lines of

function executeGetPromises() {
    var getPromises = [];
    var drivers = [];
    for (const url of [url1, url2, url3]) {
        var driver = new WebDriver.Builder().forBrowser('firefox').build();
        getPromises.push(driver.get(url));
        drivers.push(driver);
    }

    var analysePromises = [];
    int index = 0;
    Promise.all(getPromises.map(p => p.catch(e => e)))
        .then(results => {
            for (int i=0; i< results.length; i++) {
                var result = results[i];
                if (!(result instanceof Error)) {
                    analysePromises.push(AxeBuilder(drivers[i]).analyze);
                }
            }
        executeAnalysePromises(analysePromises);
    });
}

function executeAnalysePromises (analysePromises) {
    Promise.all(analysePromises.map(p => p.catch(e => e)))
    .then(results => {
        results.forEach(result => {
            if (!(result instanceof Error)) {
                console.log(result);
            }
        });
    });
}

here we are keeping a track of all the drivers, and all the driver.get promises are run in parallel and once all the getPromises return (either resolved/rejected), the analysePromises get executed in parallel.

EDIT: A more simpler approach using async functions. The above is a bit complicated, you can achieve the same using async functions

async function executeTask (driver, url) {
    try{
        await driver.get(url);
        let result = await AxeBuilder(driver).analyze();
        return Promise.resolve(result);
    } 
    catch(err) {
        return Promise.reject(err);
    }
}

function iterateThroughUrls(urls) {
    urls.forEach(url => {
        var driver = new WebDriver.Builder().forBrowser('firefox').build();
        executeTask(driver, url).then(result => {
            console.log(result);
        }).catch(err => {
            //handle errors
        });
    });
}

1 Comment

Hey Mrinal firstly thanks ! Quick question, What if I do not want this to run in parallel and serialize this exact code? It runs flawlessly the only issue is if am giving it a large number of urls, it crashes. Kindly help !

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.