我无法单击嵌套在 iFrame 中的管理按钮

I cannot click the Admin button nested inside the iFrame

我正在使用 Python 和 Selenium Webdriver 自动化我们的 Web 应用程序。 我登录到应用程序,我想单击“管理”按钮。 当我 运行 我的代码时,它无法通过我的 Xpath 找到管理按钮。我尝试了几种不同的方法。
如果我在 selenium IDE 中输入 //div[7]/div/div 并单击“查找”,它会突出显示“管理”按钮。我不知道为什么当我 运行 代码时它找不到它。 我宁愿使用 CSS 因为它比 Xpath 更快。 我需要一些帮助。

我收到以下错误:

selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: {"method":"xpath","selector":"html/body/div[2]/div[2]/div/div[2]/div/div[2]/div/div[7]/div/div"}

我检查了 HTML 元素。完整的HTML如下:

<html style="overflow: hidden;">
<head>
<body style="margin: 0px;">
<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>
</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>
</div>
</div>
<div style="position: absolute; overflow: hidden; left: 0px; top: 30px; right: 0px; bottom: 0px;">
</div>
</div>
<div style="position: absolute; overflow: hidden; top: 1px; right: 1px; width: 30px; height: 25px;">
<div style="position: absolute; overflow: hidden; left: 0px; top: -25px; right: 0px; height: 25px;">
</div>
</div>
</div>
<div style="display: none;" aria-hidden="true"></div>
</body>
</html>

我的代码如下:

element.py

from selenium.webdriver.support.ui import WebDriverWait

class BasePageElement(object):

def __set__(self, obj, value):
    driver = obj.driver
    WebDriverWait(driver, 100).until(
        lambda driver: driver.find_element_by_name(self.locator))
    driver.find_element_by_name(self.locator).send_keys(value)

def __get__(self, obj, owner):
    driver = obj.driver
    WebDriverWait(driver, 100).until(
        lambda driver: driver.find_element_by_name(self.locator))
    element = driver.find_element_by_name(self.locator)
    return element.get_attribute("value")

locators.py

from selenium.webdriver.common.by import By

class MainPageLocators(object):
Submit_button = (By.ID, 'submit')
usernameTxtBox = (By.ID, 'unid')
passwordTxtBox = (By.ID, 'pwid')
submitButton = (By.ID, 'button')
AdministrationButton = (By.CSS_SELECTOR, 'div.gwt-HTML.firepath-matching-node')
AdministrationButtonXpath = (By.XPATH, '//html/body/div[2]/div[2]/div/div[2]/div/div[2]/div/div[7]/div/div')
AdministrationButtonCSS = (By.CSS_SELECTOR, '/body/div[2]/div[2]/div/div[2]/div/div[2]/div/div[7]/div/div')
AdministrationButtonXpath2 = (By.XPATH, 'html/body/div[2]/div[2]/div/div[2]/div/div[2]/div/div[7]/div/div/text()')
AdministrationButtonXpath3 = (By.XPATH, '//div[7]/div/div')

contentFrame = (By.ID, 'ClearCore')

Page.py

from element import BasePageElement
from locators import MainPageLocators
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException

class SearchTextElement(BasePageElement):


class BasePage(object):

def __init__(self, driver):
    self.driver = driver


class LoginPage(BasePage):

search_text_element = SearchTextElement()

def userLogin_valid(self):
    userName_textbox = self.driver.find_element(*MainPageLocators.usernameTxtBox)
    userName_textbox.clear()
    userName_textbox.send_keys("riaz.ladhani")
    password_textbox = self.driver.find_element(*MainPageLocators.passwordTxtBox)
    password_textbox.clear()
    password_textbox.send_keys("test123")
    submitButton = self.driver.find_element(*MainPageLocators.submitButton)
    submitButton.click()
    #mydriver.find_element_by_xpath(xpaths['usernameTxtBox']).clear()

def clickAdministration_button(self):

    #administrationButton = self.driver.find_element(*MainPageLocators.AdministrationButton)

    content_frame = self.driver.find_element(*MainPageLocators.contentFrame)
    self.driver.switch_to.frame(content_frame)
    #self.driver.switch_to.frame(*MainPageLocators.contentFrame)
    #self.driver.Switch_to().Frame(*MainPageLocators.contentFrame)
    #administrationButtonCSS = self.driver.find_element(*MainPageLocators.AdministrationButtonCSS)
    #administrationButtonXpath= self.driver.find_element(*MainPageLocators.AdministrationButtonXpath)
    #administrationButtonXpath= self.driver.find_element(*MainPageLocators.AdministrationButton_CSS_regex)
    #administrationButtonCSS2 = self.driver.find_element(*MainPageLocators.AdministrationButtonCSS2)
    adminButton = self.driver.find_element(*MainPageLocators.AdministrationButtonXpath3)
    adminButton.click()

LoginPage_TestCase.py

import unittest
from selenium import webdriver
import page

class LoginPage_TestCase(unittest.TestCase):

def setUp(self):
    self.driver = webdriver.Firefox()
    self.driver.get("http://my-pc.company.local:8080/clearcore")

def test_login_valid_user(self):
    login_page = page.LoginPage(self.driver)
    login_page.userLogin_valid()
    login_page.ClickAdministration_button()

def tearDown(self):
    self.driver.close()

if __name__ == "__main__":
    unittest.main()

你必须使用

driver.switch_to_frame("__gwt_historyFrame");

在您管理按钮点击代码之前。这段代码会将 WebDriver 带入框架,然后只有 WebDriver 能够在框架内找到按钮, 如果你想跳出画面去外面导航, 使用

driver.switch_to_default_content()

*""__gwt_historyFrame" 这是你的框架名称

由于“管理按钮”位于id为“ClearCore”的框架下方,且不在网页中。这就是执行代码时元素无法定位的原因。

因此,在单击该按钮之前,您需要使用

切换到该框架
   1.   driver.switch_to_window("windowName")
   2.   driver.switch_to_frame("frameName")

一旦我们完成了对框架的处理,我们将不得不回到父框架,这可以使用以下方法完成:

driver.switch_to_default_content()

我终于解决了我的问题。开发人员说我必须等待页面完全加载完成。当所有元素都显示在屏幕上时,页面仍在加载 JavaScript 函数。 我首先尝试 time.sleep(30) 然后单击按钮。有效。每次等待 30 秒效率不高。然后我使用了 WebDriverWait,这样效率更高。

这是我使用的代码:

WebDriverWait(mydriver, 10).until(lambda d: mydriver.find_element_by_xpath("//div[. = 'Administration']").click())