Search code examples
javascriptnode.jsseleniumselenium-webdriverweb-component

How to click on custom web component using selenium webdriver


I'm new to writing selenium test so bear with me. I'm trying to write an automated test for a carousel element on our homepage. I want the test to click on one of the carousel navigation buttons, and then verify that some inline style was added to the carousel div. (That style will result in the carousel screen moving and showing a different item.) The nav button is a custom web element as opposed to an or a or some other obviously clickable thing. My test is failing on click(), saying "WebDriverError: element not interactable". Is this because Selenium doesn't recognize my custom web element as a clickable thing? Or am I doing something else wrong?

I've done a lot of googling and tried many different syntaxes, including adding sleeps (which I know is a big no-no). I also verified that the xpath is correct, because when I changed the xpath to something else I got a different error saying the element couldn't be found.

HTML:

<u-carousel id="hero-carousel">
    <div class="u.container"><!-- this is the element that gets the inline style added to -->
    ...carousel content here...
    </div>
</u-carousel>

<u-carousel-move class="home.hero.others active" u-for="hero-carousel" u-to="2">
    <div class="carousel-nav-button">
        Nav Item 2
    </div>
</u-carousel-move>
<u-carousel-move class="home.hero.others" u-for="hero-carousel" u-to="2">
    <div class="carousel-nav-button">
        Nav Item 3
    </div>
</u-carousel-move>

Selenium Javascript:

describe('homepage carousel', () => {
    test('carousel displays', async () => {
        expect(await carouselAppPicker()).toBe(true);
    });
});

async carouselAppPicker() {
    console.info({action: 'carouselAppPicker', status: 'run'});
    let app_picker_xpath = '//u-carousel-move[contains(@class,"home.hero.others")][@u-for="hero-carousel"][@u-to="2"]';
    let app_picker = await this.driver.wait(until.elementLocated(By.xpath(app_picker_xpath)), 5000, 'Cannot find app picker element');
    await app_picker.click();
    let carousel_screen_xpath = '//u-carousel[@id="hero-carousel"]/div[@class="u.container"][@style="transform: translateX(-200%);"]';
    await this.driver.wait(until.elementLocated(By.xpath(carousel_screen_xpath)), 5000, 'Cannot find screen element');
    return true;
}

This is the error I'm getting when I run this test from the command line using jest:

 homepage carousel › carousel displays

    WebDriverError: element not interactable
      (Session info: headless chrome=73.0.3683.103)
      (Driver info: chromedriver=2.46.628411 (hash),platform=Mac OS X 10.13.6 x86_64)

      at Object.checkLegacyResponse (node_modules/selenium-webdriver/lib/error.js:585:15)
      at parseHttpResponse (node_modules/selenium-webdriver/lib/http.js:533:13)
      at Executor.execute (node_modules/selenium-webdriver/lib/http.js:468:26)

Solution

  • Try to use the javascript to click.

    driver.executeScript("arguments[0].click()",app_picker)