Jitesh Sojitra Jitesh Sojitra - 2 months ago 19
Java Question

Selenium web driver fails to click to foreground dialog's OK button and finds background dialog's OK button

I'm using selenium web driver 3.0 and want to click to OK button from active dialog from opened two dialogs (one is in background and second is in foreground). How can i click to foreground dialog OK button from parent div from below html? I tried using nth-child and nth-of-type but click always finds first dialog showing in background and web driver fails to click to OK button.

When i check we.isDisplayed() then it finds first OK button too, i want method for we.isDisplayed() for 2nd dialog OK button.

Html:



<div id="z_shell" class="DwtShell">

<div id="Dialog1" class="DwtDialog">
<td id="ErrorDialog_button1_title" class="ZWidgetTitle">OK</td>
<td id="ErrorDialog_button2_title" class="ZWidgetTitle">Cancel</td>
</div>

<div id="Dialog2" class="DwtDialog">
<td id="ErrorDialog_button2_title" class="ZWidgetTitle">OK</td>
</div>

</div>



Note: Dialog div id can be anything, but class name is fixed: DwtDialog.


Tried code:

WebDriver webDriver;
WebElement we = webDriver.findElement(By.cssSelector("div[class='DwtDialog']:nth-child(2) td[id$='_button2_title']:contains('OK')"));
visible = we.click();
// Click fails here


Tried locators:

By.cssSelector("div[class='DwtDialog']:nth-child(2) td[id$='_button2_title']:contains('OK')")

By.xpath("//div[@class='DwtDialog'][2]//td[@id='ErrorDialog_button2_title' and contains(text(), 'OK')]")

By.xpath("//div[@id='z_shell']//div[@class='DwtDialog'][2]//td[@id='ErrorDialog_button2_title' and contains(text(), 'OK')]")


Problem:


How can i click to OK button of dialog which is visible? Mostly this dialog is loaded later. I meant nth-child(2) and for 3rd dialog nth-child(3) as a hint.


Thanks for reading and help appreciated!

Answer

EDIT: I missed the comment about the id's changing... try #2. I think something like this should work but I can't test it without the page. Basically we grab all the buttons td.ZWidgetTitle on dialogs div.DwtDialog. If it is visible and contains "OK", click it.

List<WebElement> dialogButtons = driver.findElements(By.cssSelector("div.DwtDialog > td.ZWidgetTitle"));
for (WebElement dialogButton : dialogButtons)
{
    if (dialogButton.isDisplayed() && dialogButton.getText().equals("OK"))
    {
        dialogButton.click();
        break;
    }
}

EDIT 2:

After getting more info, here's another approach. It's hard to figure out if this stuff will work without access to the site but this will hopefully point you in the right direction if it doesn't work. This will get all the OK buttons on error dialogs. The problem is, which one is clickable? We can eat the exception that is thrown when another element would receive the click until we find one that doesn't throw... that's the right one. I did some local testing and this code seems to work for me.

List<WebElement> dialogButtons = driver.findElements(By.xpath("//td[starts-with(@id, 'ErrorDialog_button') and text()='OK']"));
System.out.println(dialogButtons.size());
System.out.println(dialogButtons.size());
for (WebElement dialogButton : dialogButtons)
{
    try
    {
        dialogButton.click();
    }
    catch (WebDriverException e)
    {
        // do nothing
    }
}