简体   繁体   English

Selenium webdriver无法单击页面外的链接

[英]Selenium webdriver can't click on a link outside the page

I am having an issue with Selenium WebDriver. 我遇到了Selenium WebDriver的问题。 I try to click on a link that is outside the window page (you'd need to scroll up to see it). 我尝试单击窗口页面外的链接(您需要向上滚动才能看到它)。 My current code is fairly standard: 我目前的代码是相当标准的:

menuItem = driver.findElement(By.id("MTP"));
menuItem.click();
// I also tried menuItem.sendKeys(Keys.RETURN);

I know I could scroll up, and it would work in this case. 我知道我可以向上滚动,在这种情况下它会起作用。 But in a case where you have a long list of items, you don't necessarily know how far you have to scroll down. 但是如果你有很长的项目列表,你不一定知道你需要向下滚动多远。

Is there any way to click on a link that is not on the visible part of the page (but that would be visible if you scroll)? 有没有办法点击不在页面可见部分的链接(但滚动时会显示)?

As a side note, I'm using Firefox, but I am planning to use IE7/8/9 and Chrome as well. 作为旁注,我正在使用Firefox,但我打算也使用IE7 / 8/9和Chrome。

Any help would be greatly appreciated. 任何帮助将不胜感激。

Edit: I'm afraid I can't give the source code, as the company I work for doesn't allow it, but I can give the code of the link I want to click on: 编辑:我担心我不能提供源代码,因为我工作的公司不允许它,但我可以给出我想点击的链接的代码:

<div class="submenu">
  <div id="MTP">Link title</div>
</div>

The exact same code works when the link is visible, only when it is not does it not work. 链接可见时,完全相同的代码有效,只有当链接不可用时才能使用。

Edit2: Actually, oddly enough, it doesn't raise any exception and just goes to the next instruction. 编辑2:实际上,奇怪的是,它不会引发任何异常,只是转到下一条指令。 So basically, what happens is: 所以基本上,会发生什么:

menuItem = driver.findElement(By.id("MTP")); // no exception
menuItem.click();  // no exception
//... some code ensuring we got to the next page: timeout reached
driver.findElement(By.id("smLH")).click(); // NoSuchElementException, as we're on the wrong page.

It is actually possible to scroll automatically to element. 实际上可以自动滚动到元素。 Although this is not a good solution in this case (there must be a way to get it working without scrolling) I will post it as a workaround. 虽然在这种情况下这不是一个好的解决方案(必须有一种方法可以让它在不滚动的情况下工作),我会将其作为一种解决方法发布。 I hope someone will come up with better idea... 我希望有人能提出更好的想法......

public void scrollAndClick(By by)
{
   WebElement element = driver.findElement(by);
   int elementPosition = element.getLocation().getY();
   String js = String.format("window.scroll(0, %s)", elementPosition);
   ((JavascriptExecutor)driver).executeScript(js);
   element.click();
}

I ran into a similar problem recently when there was a list of selectable objects in a JS dialog. 最近,当JS对话框中有可选对象列表时,我遇到了类似的问题。 Sometimes selenium would not select the correct object in the list. 有时selenium不会在列表中选择正确的对象。 So i found this javascript suggestion: 所以我发现这个javascript建议:

WebElement target = driver.findElement(By.id("myId"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", target);
Thread.sleep(500); //not sure why the sleep was needed, but it was needed or it wouldnt work :(
target.click();

That solved my issue 这解决了我的问题

I posted this same answer in another question so this is just a copy and paste. 我在另一个问题中发布了相同的答案,所以这只是一个复制和粘贴。

I once had a combo box that wasn't in view that I needed to expand. 我曾经有一个组合框,我不需要扩展它。 What I did was use the Actions builder because the moveToElement() function will automatically scroll the object into view. 我所做的是使用Actions构建器,因为moveToElement()函数会自动将对象滚动到视图中。 Then it can be clicked on. 然后可以点击它。

WebElement element = panel.findElement(By.className("tabComboBoxButton"));

Actions builder = new Actions(this.driver);

builder.moveToElement(element);
builder.click();
builder.build().perform();

(panel is simply a wrapped element in my POM) (面板只是我POM中的一个包裹元素)

Instead of move the scrollbar to the button position, which sometimes it didn't work for me, I send the enter key to the button 而不是将滚动条移动到按钮位置,有时它对我不起作用,我将回车键发送到按钮

var element = driver.FindElement(By.Id("button"));
element.SendKeys(Keys.Enter);

Hey you can use this for ruby 嘿,你可以用这个红宝石

variable.element.location_once_scrolled_into_view

Store the element to find in variable 存储元素以在变量中查找

It might be occurring because your header element or the footer element might be blocking the view of the element you want to perform action on. 可能是因为您的标题元素或页脚元素可能阻止了您要对其执行操作的元素的视图。 Selenium tries to scroll to the element position when it has to perform some action on the element (I am using Selenium WebDriver v3.4.0). 当Selenium必须对元素执行某些操作时,它会尝试滚动到元素位置(我使用的是Selenium WebDriver v3.4.0)。

Here is a workaround - 这是一个解决方法 -

private WebElement scrollToElementByOffset(WebElement element, int offset) {
    JavascriptExecutor jse = (JavascriptExecutor) driver;
    jse.executeScript("window.scrollTo(" + element.getLocation().getX() + "," + (element.getLocation().getY()
            + offset) + ");");

    return element;
}

The above function scrolls the view to the element and then scrolls further by the offset you provide. 上面的函数将视图滚动到元素,然后进一步滚动您提供的偏移量。 And you can call this method by doing something like - 您可以通过执行以下操作来调用此方法:

WebElement webElement = driver.findElement(By.id("element1"));
scrollToElementByOffset(webElement, -200).click();

Now, this is just a workaround. 现在,这只是一种解决方法。 I gladly welcome better solutions to this issue. 我很高兴欢迎更好地解决这个问题。

This solution worked like a charm for me: 这个解决方案对我来说就像一个魅力:

public void click(By by) throws Exception{
    WebElement element = driver.findElement(by);
    ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
    Thread.sleep(500);
    element.click();
}

This works for me (in c#)- 这对我有用(在c#中) -

item = driver.findelement(by.....);
item.SendKeys(Keys.LeftControl);
item.Click();

Just an addition: In my case the button was overlapped by another floating button. 只是一个补充:在我的情况下,按钮与另一个浮动按钮重叠。

Just resizing the browser window solved the problem! 只需调整浏览器窗口大小即可解决问题!

I used the method below to solve a similar issue for Selenium Java: 我使用下面的方法来解决Selenium Java的类似问题:

public static void scrollToElementByElement(WebElement element) {

    Coordinates coordinates = ((Locatable)element).getCoordinates();
    coordinates.inViewPort();
    coordinates.click(); //if needed

}

Then called on the method on my main test class 然后在我的主测试类上调用该方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM