Click() 方法并不总是有效

Posted

技术标签:

【中文标题】Click() 方法并不总是有效【英文标题】:Click() method will not always work 【发布时间】:2012-08-22 23:56:05 【问题描述】:

我在 Selenium WebDriver 中的测试有问题。当程序尝试单击按钮时,Click 事件并不总是有效。在一项测试中一切正常,在其他测试中则不然。

每个测试都从一页开始。首先,用户必须从select 组件中选择一个选项,然后用户单击一个按钮。

我想知道为什么第一次一切正常,而当我第二次运行测试时却不行?

这里是找到并点击按钮的源代码:

public void clickContinueBtn()     
    webElement = driver.findElement(By.xpath("//div[@class='btn magenta_s']/a/span"));
    webElement.click(); 

【问题讨论】:

@saumil 说:非常感谢这对我有用 相关帖子 - ***.com/questions/43011751/… 【参考方案1】:

造成这种情况的一个可能原因是click() 方法无法在每个元素上调度click 事件。

因此,您可以在您尝试点击的元素上显式触发 click 事件。

【讨论】:

但是当我在其他页面上的组件(也是按钮)上调用 click() 事件时,它可以工作。 就是这样。有时它会发生click() 能够在某些元素上触发事件,而在同一页面上的其他元素上它也无法触发。因此尝试显式触发点击事件。 抱歉,“明确”是什么意思?【参考方案2】:

您也可以尝试使用基于 javascript 的替代方法进行点击。代码如下:

WebElement element = driver.findElement(By.id("something"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);

【讨论】:

它不起作用。选择组件的一个选项选择浏览器窗口时才结束。 span> 在尝试了几乎所有其他选项后为​​我工作,谢谢!【参考方案3】:

我遇到了类似的问题。 click 方法在其他页面上起作用,然后在特定页面上根本不起作用。

竞争条件导致了问题:

    在禁用按钮的情况下呈现 html 内容。 在触发 javascript onload 事件之前执行了 selenium Web 驱动程序脚本(或完成执行)。所以button.click 会出现在禁用的元素上。什么都不会发生。 然后 javascript onload 事件将触发 (或完成执行) 并且 javascript 将启用按钮。 我查看了该页面,但无法弄清楚为什么我的代码不起作用,因为在检查时该按钮似乎已启用,并且如果我手动单击该按钮,它就起作用了。

一旦我发现这是一个时间问题,我在这里找到了解决方案:How can I get Selenium Web Driver to wait for an element to be accessible, not just present?

用 Ruby 解释解决方案:

//This will not return the button until it is enabled.
button = driver.find_element(:xpath,  "//button[@id='myButtonId' and not(@disabled)]")
button.click

【讨论】:

这对我很有帮助,该脚本在其他浏览器中运行良好,但在 Safari 6 和 android 浏览器中却没有,它们速度不够快。感谢分享这个答案! :) 如何切换做 iframe 并等待 onload="javascript:pageload();functionalPageLoad();"在 Ruby 中重新加载页面?我发现自己在页面内打开 iframe,我可以访问它,然后页面重新加载,我无法再访问该框架。我已经阅读了很多关于等待、睡眠、时间、切换到框架然后切换到父级的答案,但是我无法达到我的目标。 如果您的元素仅保持禁用几毫秒,您如何发现您的元素已禁用?在我的情况下,点击在 selenium 第一次尝试后 1-2 秒起作用。 @testerjoe2 - ***.com/questions/6727370/… 在元素上使用断点或更改元素状态的 javascript 将其设置为“启用”。使用它来验证元素加载为禁用。 @AmandaC.Cavallaro 对于极度延迟和糟糕的回答,我深表歉意。这可能会有所帮助。 ***.com/questions/9942928/…【参考方案4】:

几天前我遇到了类似的问题,我在我的特定案例中找到了解决方案。 ===使用 Selenium Webdriver,我想点击“First Link”的链接,这将在页面上加载内容。

下面是结构与我的情况相似的部分代码:

<li class="first-link">
    <a class="common-style" href="javascript:;" style="padding-left: 15px; padding-right: 15px;">First Link</a>
</li>

===结果是应该找到并单击 Web 元素,但切换到 UI,没有发生任何事情,也没有引发错误(未找到元素、未准备好单击元素、禁用元素等)。

在尝试了几种不同的方法来查找链接之后(xpath 和 css,没有尝试通过 id,因为在我的情况下没有唯一的 id),我能够通过 css 访问并单击 Selenium webdriver 的元素以下值:li.first-link a。 但是,当我尝试通过具有以下值的 xpath 访问时,这是在 Firefox 中“找到”但单击不起作用:.//li[a/text()='First Link']

问题是一个轻微的xpath语法问题,Firefox的firebug根本没有报告,实际上它找到了链接。

我改变了大括号的顺序是这样的:.//li/a[text()='First Link'] 现在它按预期工作,找到并单击了第一个链接,并触发了加载页面的 javascript 代码。

我的发现是: * 这不是时间问题,因此不会发生这种情况,因为您尝试单击未准备好的元素。否则我们已经通过显式的 Selenium 等待解决了这个问题......

问题不在于找到了元素并且没有触发 javascript。您可以尝试直接执行 javascript 代码并手动触发事件,然后发现这不起作用。 此问题发生在 Firefox 22 上,可能适用于该浏览器的旧版本。如果这适用于 IE 或 Chrome,我无法提供信息。问题本身是,即使 xpath firefox 上存在语法冲突也不会引发异常,这让您认为您的代码没有任何问题,但确实存在。 这是 Firefox 的意外未处理行为。我发现了一个报告的错误: http://code.google.com/p/selenium/issues/detail?id=4757

建议的解决方案:验证您的 html 结构、xpath,尝试找出语法问题,找到访问元素的不同方式。

【讨论】:

【参考方案5】:

查看您的 xpath,您尚未确定按钮,而是指向其中存在按钮的 span 标签。 Selenium 点击 span 而不是按钮。这就是 click() 不起作用的原因。请使用 ID 或名称(如果可用)或更改 xpath 以包含按钮标签。如果您可以发布 html,那么创建 xpath 将很容易。 click() 对我来说效果很好,我在一个项目中使用这种方法已经一年多了,而且每次都能正常工作......

【讨论】:

【参考方案6】:

您确定不存在时间问题吗?在找到元素之前创建一个断点并查看您的代码是否运行良好。如果存在时间问题,请在单击按钮之前使用显式等待。另请注意,在实际单击按钮之前,该按钮应该是可单击的(元素必须可见且已启用)。

显式等待的解决方案可能如下所示:

By by = By.xpath("//div[@class='btn magenta_s']/a/span");
WebDriverWait w = new WebDriverWait(driver, timeout);
WebElement element = w.waitUntil(ExpectedConditions.elementToBeClickable(by);
element.click();

【讨论】:

似乎 w.waitUntil 已被 w.until 替换,即 WebElement element = wait.until(ExpectedConditions.elementToBeClickable(selector));【参考方案7】:

试试下面的代码有时你故意将注意力转移到你的元素上

WebElement element = driver.findElement("yourElement");
        Actions builder = new Actions(driver);
        builder.moveToElement(element).click(element);
        builder.perform();

【讨论】:

【参考方案8】:

由于浏览器兼容性(主要是在 firefox 上),这种情况经常发生。所以尝试使用 “WebElement.sendKeys(Keys.ENTER);” 代码而不是 "webElement.click();"

【讨论】:

【参考方案9】:

您可以尝试使用 JavaScriptExecutor 或 Action 类。

//JSExecutor
WebElement element = driver.findElement(By.xpath("xpathofyourelement"));
JavascriptExecutor jsExecutor = (JavascriptExecutor)driver;
jsExecutor.executeScript("arguments[0].scrollIntoView();", element);
jsExecutor.executeScript("arguments[0].click();", element);

//Action Class
WebElement element = driver.findElement(By.xpath("xpathofyourelement"));
Actions builder = new Actions(driver);
builder.moveToElement(element).click(element);
builder.perform();

干杯..!!

【讨论】:

以上是关于Click() 方法并不总是有效的主要内容,如果未能解决你的问题,请参考以下文章

为啥 QSplashscreen 并不总是有效?

条件变量并不总是有效

Angular2 Click 方法总是返回 false 值

removeFromSuperview() 并不总是有效

为啥 constexpr 隐式转换并不总是有效?

IE、XDomainRequest 并不总是有效