0

I am automating our website using Webdriver with Python. I am having trouble identifying and clicking the Administration button. I was trying to switch to the iFrame and select the button. It wasn't finding the button.
I have spoken to the Dev and the developer says it's not in an iFrame. The GUI is done in GWT.
I just need to work out the CSS or XPath so i can click the button.
CSS would be better as it is faster than XPath.

I have tried the following XPath: //div[@class="gwt-TabLayoutPanelTabs"]/div[last()]

It highlights the background colour of the button when i test it in the Selenium IDE using the Find button.

Does anyone know the CSS or absolute XPath please?

The HTML is as follows (Administration is the last div at the bottom):

<html style="overflow: hidden;">
<head>
<body style="margin: 0px;">
<iframe id="__gwt_historyFrame" style="position: absolute; width: 0; height: 0; border: 0;" tabindex="-1" src="javascript:''">
<html>
<head>
</head>
<body>
</html>
</iframe>
<noscript> <div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif;"> Your web browser must have JavaScript enabled in order for this application to display correctly.</div> </noscript>
<script src="spinner.js" type="text/javascript">
<script type="text/javascript">
<script src="ClearCore/ClearCore.nocache.js" type="text/javascript">
<script defer="defer">
<iframe id="ClearCore" src="javascript:''" style="position: absolute; width: 0px; height: 0px; border: medium none;" tabindex="-1">
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
<script type="text/javascript">
<script type="text/javascript">
</head>
<body>
</html>
</iframe>
<div style="position: absolute; z-index: -32767; top: -20cm; width: 10cm; height: 10cm; visibility: hidden;" aria-hidden="true"> </div>
<div style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;">
<div style="position: absolute; z-index: -32767; top: -20ex; width: 10em; height: 10ex; visibility: hidden;" aria-hidden="true"> </div>
<div style="position: absolute; overflow: hidden; left: 0px; top: 0px; right: 0px; bottom: 0px;">
<div style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;">
<div style="position: absolute; z-index: -32767; top: -20ex; width: 10em; height: 10ex; visibility: hidden;" aria-hidden="true"> </div>
<div style="position: absolute; overflow: hidden; left: 1px; top: 1px; right: 1px; bottom: 1px;">
<div class="gwt-TabLayoutPanel" style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px;">
<div style="position: absolute; z-index: -32767; top: -20ex; width: 10em; height: 10ex; visibility: hidden;" aria-hidden="true"> </div>
<div style="position: absolute; overflow: hidden; left: 0px; top: 0px; right: 0px; height: 30px;">
<div class="gwt-TabLayoutPanelTabs" style="position: absolute; left: 0px; right: 0px; bottom: 0px; width: 16384px;">
<div class="gwt-TabLayoutPanelTab GEGQEWXCK gwt-TabLayoutPanelTab-selected" style="background-color: rgb(254, 255, 238);">
<div class="gwt-TabLayoutPanelTab GEGQEWXCK" style="background-color: rgb(254, 255, 238);">
<div class="gwt-TabLayoutPanelTab GEGQEWXCK" style="background-color: rgb(254, 255, 238);">
<div class="gwt-TabLayoutPanelTab GEGQEWXCK" style="background-color: rgb(254, 255, 238);">
<div class="gwt-TabLayoutPanelTab GEGQEWXCK" style="background-color: rgb(254, 255, 238);">
<div class="gwt-TabLayoutPanelTab GEGQEWXCK" style="background-color: rgb(254, 255, 238);">
<div class="gwt-TabLayoutPanelTab GEGQEWXCK" style="background-color: rgb(254, 255, 238);">
<div class="gwt-TabLayoutPanelTabInner">
<div class="gwt-HTML">Administration</div>
</div>
</div>   

My Admin button code:

adminButton = mydriver.find_element_by_xpath('//div[@class="gwt- TabLayoutPanelTabs"]/div[last()]')
adminButton.click()

I have also tried:

mydriver.find_element_by_xpath('//div[7]/div/div').click()
Riaz Ladhani
  • 3,946
  • 15
  • 70
  • 127

2 Answers2

4

You need to locate the nested iframes and switch to them one by one before finding an element inside:

driver.switch_to.frame("__gwt_historyFrame")
driver.switch_to.frame("ClearCore")

administration = driver.find_element_by_xpath("//div[. = 'Administration']")
administration.click()

Note that I'm locating the element by text, which, I think, is more "natural" and logical.

If the "Administration" link is not inside an iframe, omit the two "switch_to" lines.

You may also need to wait for the element to become clickable:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

administration = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "//div[. = 'Administration']"))
)
administration.click()
Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • Thanks for the suggestion. I get the error Unable to locate frame: ClearCore. If i comment out the first line at frame "_gwt_historyFrame" Run the code, I get the following error: Unable to locate element: {"method":"xpath","selector":"//div[. = 'Administration']"} – Riaz Ladhani May 06 '15 at 15:58
  • @RiazLadhani are you sure that the provided markup is actually correct? Is the site public and you can share the link to it? If not, at least, add closing `iframe` tags. Thanks. – alecxe May 06 '15 at 16:02
  • The URL is not a public URL. The website is hosted on local machine in Tomcat. E.g. URL: http://vmtest01:8080/clearcore The iFrame html I cannot see a closed iFrame tag. – Riaz Ladhani May 06 '15 at 16:10
  • The html where the Administration div is as follows:
    Administration
    – Riaz Ladhani May 06 '15 at 16:10
  • Sorry I have found the iFrame closed tag. It is as follows: – Riaz Ladhani May 06 '15 at 16:12
  • Just spoke to the dev. The Administration div is outside of the iFrame. The iFrame loads the Javascript. They suggest waiting for the page to have loaded – Riaz Ladhani May 06 '15 at 16:26
  • @RiazLadhani okay, thanks for the updates. I've updated the answer providing more information. I think that's all I can suggest at this moment having this much information. Check it out. – alecxe May 06 '15 at 22:35
  • Thanks for the updated answer. I get no errors now when i run my script with your Wait code. It does not click the button. I tried increasing the delay from 10 to 200 as the page does take time to load. Still no luck. I am thinking maybe i need to use the JavaScript Executor function to find the element. – Riaz Ladhani May 07 '15 at 09:36
  • @RiazLadhani if you don't get any errors including timeout error, this means it actually finds the element and clicks it. But nothing happens - are you sure this "administration" div is clickable? – alecxe May 07 '15 at 09:38
  • Thanks for the updated answer. I get no errors now when i run my script with your Wait code. It still does not click the button. I tried increasing the delay from 10 to 200 as the page does take time to load. Still no luck. I am thinking maybe i need to use the JavaScript Executor function to find the element. In the HTML tag inside the iFrame tag I can see there is a lot of JavaScript being loaded. – Riaz Ladhani May 07 '15 at 10:15
  • I have looked at other threads with similar issues. I have found as the website front end is translated into JavaScript. I need to use the JavaScript Executor function to locate and click the Administration button. I have tried the following but my syntax is wrong. I need a little help on the syntax please. mydriver.execute_script("document.getElementByXpath("//div[. = 'Administration']") – Riaz Ladhani May 08 '15 at 14:46
2

I Have finally managed to solve my issue. The dev said I had to wait for the page to have fully completed loading. The page was still loading the JavaScript functions when all the elements were displayed on the screen.
I first tried time.sleep(30) then click the button. It worked. Waiting for 30 secs every time is not efficient. I then used WebDriverWait and this is more efficient. Here is the code i used:

WebDriverWait(mydriver, 10).until(lambda d: mydriver.find_element_by_xpath("//div[. = 'Administration']").click())
Riaz Ladhani
  • 3,946
  • 15
  • 70
  • 127