javaseleniumselenium-webdriverselenium-chromedriverkatalon-recorder

Why does the same button need different element locators to work?


I'm new in Web Automation and I want to start with a simple question.

I'm working with Selenium Webdriver in Chrome. I have a button on every page I test:

<button class="next_btn btn green">Btn</button>

The first time I had to write the following syntax to get it working:

driver.findElement(By.xpath("//button[contains(.,'Btn')]")).click();

Other xpaths didn't work. Next time I had to use this:

driver.findElement(By.xpath("//*[@id=\'formtop\']/div/form/div/fieldset[2]/div[2]/button[2]")).click();

And the same button on the next page won't accept anything.

I tried:

WebElement stupidBtn = driver.findElement(By.xpath("//*[@id=\'formtop\']/div/form/div/fieldset[3]/div[2]/button[2]"));
stupidBtn.click();


driver.findElement(By.xpath("//*[@id=\'formtop\']/div/form/div/fieldset[3]/div[2]/button[2]")).click();


WebElement stupidBtn = driver.findElement(By.xpath("//*[@id=\'formtop\']/div/form/div/fieldset[3]/div[2]/button[2]"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", stupidBtn);


WebElement stupidBtn = driver.findElement(By.id("//*[@id=\'formtop\']/div/form/div/fieldset[3]/div[2]/button[2]"));
Actions buildAct = new Actions(driver);
buildAct.moveToElement(stupidBtn).click(stupidBtn);
buildAct.perform();


driver.findElement(By.cssSelector("#formtop>div>form>div>fieldset:nth-child(3)>div.multiform_buttons>button.next_btn.btn.green")).click();

In general I want to know what I'm not understanding and why I can't use always the same syntax like in Katalon Automation Recorder. Unfortunately KAR isn't able to cover up all my needs.

Thanks and regards


Solution

  • The behaviour you describe may happen if the "pages" you're talking about are not real page transitions, but each "next button" press is dynamically updating the same page.

    I've seen multiple "multi-page" forms in the past that are all on the same page, but show and hide different "pages" depending on which section of the form a user is on.

    So when you attempt to use the first locator on the second button, it still locates the first, attempts to interact with it, and throws an exception that the element is not visible/able to be interacted with.

    In the past I've built solutions for this based on using findElements and then looping those elements to click the one that is currently displayed.

    ArrayList<WebElement> elements = (ArrayList<WebElement>) driver.findElements(By.xpath("//button[contains(.,'Btn')]"));
    for(WebElement element : elements) {
        if(element.isDisplayed()) {
            element.click();
        }
    }
    

    Without seeing the page I can't say whether this is definitely the case, but it's a possibility.