Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Quality Assurance Introduction to Selenium Automation Nation A Fork in the XPath

Dylan Macnab
Dylan Macnab
24,861 Points

Getting the wrong order of invitees and "Unhandled promise rejection" error

I'm having two issues on this step.

  1. The order of the invitees are all out of sync and some are missing names or have multiple names. I'm thinking it has to do with the forEach method because it doesn't happen when I manually add names using the addInvitee() functions on their own.

  2. I'm getting this error in my console from the removeInvitee() function:

(node:19360) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): NoSuchElementError: no such element: Unable to locate element: {"method":"xpath","selector":"//span[text()="Dylan Macnab"]/../button[last()]"}
  (Session info: chrome=66.0.3359.181)
  (Driver info: chromedriver=2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X 10.13.1 x86_64)
(node:19360) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I'm using node v8.8.1. Any help is appreciated, thanks!

const selenium = require("selenium-webdriver");
const By = selenium.By;

const driver = new selenium.Builder()
  .forBrowser("chrome")
  .build();

driver.get(process.env.URL);

const invitees = [
  'Dylan Macnab',
  'Shadd Anderson',
  'George Aparece',
  'Shadab Khan',
  'Joseph Michael Casey',
  'Jennifer Nordell',
  'Faisal Albinali',
  'Taron Foxworth',
  'David Riesz',
  'Maicej Torbus',
  'Martin Luckett',
  'Joel Bardsley',
  'Reuben Varzea',
  'Ken Alger',
  'Amrit Pandey',
  'Rafal Rudzinski',
  'Brian Lynch',
  'Lupe Camacho',
  'Luke Fiji',
  'Sean Christensen',
  'Philip Graf',
  'Mike Norman',
  'Michael Hulet',
  'Brent Suggs'
];

const locators = {
  inviteeForm: By.id("registrar"),
  inviteeNameField: By.css("#registrar input[name='name']"),
  toggleNonRespondersVisibility: By.css(".main > div input"),
  removeButtonForInvitee: invitee => By.xpath(`//span[text()="${invitee}"]/../button[last()]`)
}

function addInvitee(name) {
  driver.findElement(locators.inviteeNameField).sendKeys(name);
  driver.findElement(locators.inviteeForm).submit();
}

function removeInvitee(name) {
  driver.findElement(locators.removeButtonForInvitee(name)).click();
}

function toggleNonRespondersVisibility() {
  driver.findElement(locators.toggleNonRespondersVisibility).click();
}

invitees.forEach(addInvitee);
removeInvitee("Dylan Macnab");

Hi,

Sorry I'm unable to answer the question, but I am also having a similar issue.

The order is correct, but I'm getting the UnhandledPromiseRejection, NoSuchElementError.

However, in devtools, the xpath locator works.

The error output and my code is below.

Error Output

(node:16575) UnhandledPromiseRejectionWarning: NoSuchElementError: no such element: Unable to locate element: {"method":"xpath","selector":"//span[text() = "Shadd Anderson"]/../button[last()]"}
  (Session info: chrome=68.0.3440.33)
  (Driver info: chromedriver=2.40.565386 (45a059dc425e08165f9a10324bd1380cc13ca363),platform=Mac OS X 10.13.5 x86_64)
    at Object.checkLegacyResponse (/Users/berianlowe/treehouse/qa/selenium-basics/node_modules/selenium-webdriver/lib/error.js:585:15)
    at parseHttpResponse (/Users/berianlowe/treehouse/qa/selenium-basics/node_modules/selenium-webdriver/lib/http.js:533:13)
    at Executor.execute (/Users/berianlowe/treehouse/qa/selenium-basics/node_modules/selenium-webdriver/lib/http.js:468:26)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:16575) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:16575) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handledwill terminate the Node.js process with a non-zero exit code.

Index.js

const selenium = require("selenium-webdriver");

const By = selenium.By;

const driver = new selenium.Builder()
    .forBrowser("chrome")
    .build();

const invitees = [
    'Gonzalo Torres del Fierro',
    'Shadd Anderson',
    'George Aparece',
    'Shadab Khan',
    'Joseph Michael Casey',
    'Jennifer Nordell',
    'Faisal Albinali',
    'Taron Foxworth',
    'David Riesz',
    'Maicej Torbus',
    'Martin Luckett',
    'Joel Bardsley',
    'Reuben Varzea',
    'Ken Alger',
    'Amrit Pandey',
    'Rafal Rudzinski',
    'Brian Lynch',
    'Lupe Camacho',
    'Luke Fiji',
    'Sean Christensen',
    'Philip Graf',
    'Mike Norman',
    'Michael Hulet',
    'Brent Suggs'
 ];
driver.get(process.env.URL);

const locators = {
    inviteeForm: By.id("registrar"),
    inviteeNameField: By.css("#registrar input[name='name']"),
    toggleNonRespondersVisibility: By.css (".main > div input"),
    removeButtonForInvitee: invitee => By.xpath(`//span[text() = "${invitee}"]/..//button[last()]`)
};

function addInvitee(name) {
    driver.findElement(locators.inviteeNameField)
        .sendKeys(name);

    driver.findElement(locators.inviteeForm).submit();
}

function removeInvitee(invitee) {
    driver.findElement(locators.removeButtonForInvitee(invitee))
        .click();
}

function toggleNonRespondersVisibility() {
    driver.findElement(locators.toggleNonRespondersVisibility)
    .click();
}

invitees.forEach(addInvitee);
removeInvitee("Shadd Anderson");

// toggleNonRespondersVisibility();

Been scratching my head for the last hour and can't see anything wrong with the code.

Many thanks, Berian

3 Answers

Brian Pedigo
Brian Pedigo
26,783 Points

I was having the same problems as listed above. I was able to get the code working by changing the code in two places.

First I used regular concatenation isn't of template literals.

removeButtonForInvitee: invitee => By.xpath('//span[text()="' + invitee +'"]/../button[last()]')

Second, the html and css wasn't finished being built by the first function therefore, the call to removeInvitee() would fail. I fixed this by using the setTimeout function.

 setTimeout(removeInvitee, 5000, "Shadd Anderson");

After that those changes it worked as show in the video.

Simon McGuirk
Simon McGuirk
2,673 Points

Also having the same issue. It looks like the script is trying to identify the element before the list has completed being added hence not finding the element. I've been trying to workout how to make the script wait before trying to find the element but so far have not been successful. Hopefully @craigdennis can add this in a future revision to avoid people getting stuck at this point.

Natalia-Antonia Baluta
Natalia-Antonia Baluta
6,079 Points

I have the same problem, I'm really disappointed to see that nobody answered for almost one year. I think I'm just gonna skip.