Hfrav Hfrav - 9 months ago 30
C# Question

*Problems finding specific element on page

I know there are existing questions on this topic, but none of them seems to help me with this:

I've got a lightbox with several elements.
I can find and access all of these elements, except ONE, using the XPath.

These are the items:

Text header: No problem

Text: No problem

Input field: No problem

Text: No problem

Text: No problem

Button (upload file): THIS IS SEEMINGLY IMPOSSIBLE FOR Selenium TO FIND

Button (cancel): No problem

Button (send): No problem

The XPaths for all the elements:

.//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[1] /content-placeholder/h1
.//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[3]/content-placeholder/ul[1]/li[1]/label/span
.//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[3]/content-placeholder/ul[1]/li[1]/div/div/input
.//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[3]/content-placeholder/label
.//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[3]/content-placeholder/span
.//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[3]/content-placeholder/a/input
.//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[5]/content-placeholder/button[1]
.//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[5]/content-placeholder/button[2]


The problematic element is this:

.//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[3]/content-placeholder/a/input


As far as I can see, there's no reason why it should be different from the other elements (textfield, button, text)?

I'm accessing all these elements with an implicit wait, to check that they've all loaded before continuing.

GCDriver.WaitForVisible("//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[3]/content-placeholder/a/input");


From the GCDriver (Selenium Driver) class:

public static void WaitForVisible (string xpath) {
var wait = new WebDriverWait(GCDriver.Instance,
TimeSpan.FromSeconds(10));
wait.Until(driver =>
driver.FindElement(By.XPath(xpath)).Displayed);
}


Now, as mentioned, this works for all the other elements, as well as accessing them directly. For this, the wait times out with WebDriverTimeoutEsception:

Result Message:
Test method Tests.Regression_tests.VerifyOverlays.Verify_Update_Ticket_OverlayContent threw exception:
OpenQA.Selenium.WebDriverTimeoutException: Timed out after 10 seconds


Also, of course, trying to ACCESS the button with .Click() also fails:

GCDriver.Instance.FindElement(By.XPath(".//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[3]/content-placeholder/a/input")).Click();

Result Message:
Test method Tests.Regression_tests.VerifyOverlays.Verify_Update_Ticket_OverlayContent threw exception:
System.InvalidOperationException: unknown error: Element is not clickable at point (-208, 307)


Here's the html code for the element:

<a class="btn btn-grey file-input-container btn-small" data-bind="enable: !uploading() "
style="margin-top: 10px; padding: 7px 12px; "data-tooltipped=""
aria-describedby="tippy-tooltip-32"
data-original-title="Add Attachment">
<i class="fa fa-cloud-upload"/>
<span class="mq-for-small-hide">
<span localize-me="">Add Attachment</span>
</span>
<input data-bind="upload: addAttachments,
enable: !uploading()" type="file"/>
</a>


I've tried some other ways of getting the element, but since this is quite (imo) "messy" html, with no unique ID's or good class names, I've been unable to figure out how.

And it REALLY bugs me that I cannot find it by the XPath. There are 8 elements on the page, all visible and accessible, but this ONE element is impossible to find with Selenium.

The element is there; I can manually click the button on the page while Selenium runs it.

UPDATE:
I also tried using .Enabled instead of .Displayed. Same result.

UPDATE 2:
There are two answers below, and I have to select one as the "winner".

Shubham Jain gives an answer that, while not the exact thing I was trying to to, is a very good work-around. By using JavaScriptExecutor to try clicking the button, it also checks if the button is visible. However, the answer given doesn't do what it tries to do; Clicking doesn't work quite that way. See Solution below to see the correct/working code to click a button using JavaScriptExectutor.

smit9234's answer is exactly what I'm trying to do, although clicking doesn't work that way. To click the button, JS is necessary in this case. However, the question was how to check .Displayed, and that works with the modified XPath he gave me from the code excerpt.

Solution

The XPath of the element (button) is, according to FirePath:

.//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[3]/content-placeholder/a/input


This, however, doesn't work. Selenium simply cannot find it, even though it's clearly there.

THIS XPath, however, does work:

.//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[3]/content-placeholder/a/span/span


However, it works with reagards to the .Displayed check. It does NOT work with Click(). To be able to click the button, I began with Shubham Jain's code example and created this method in the Driver class, to be able to use JavaScript (with Selenium's JavaScriptExecutor) to click the button:

using OpenQA.Selenium.Interactions;

public static void JSClick (string xpath) {
IWebElement icon = Instance.FindElement(By.XPath(xpath));
Actions ob = new Actions(Instance);
ob.Click(icon);
IAction action = ob.Build();
action.Perform();
}

Answer Source

Looking at the html snippet you posted, it seems like this is a file attachment function. Based on the html structure of the snippet, try using the following xpath:

.//*[@id='overlays']/overlay--master/div/div/overlay-lightbox/div/div[3]/content-placeholder/a/span/span

You should then be able to use the click(); method to click the "Add Attachments"

I assume that clicking on the input doesn't do anything, however you should be able to use the sendKeys(); method for sending the "file path" to the input element.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download