*在页面上查找特定元素的问题

时间:2017-08-16 11:43:59

标签: c# selenium selenium-webdriver visual-studio-2015 selenium-chromedriver

我知道有关于这个主题的问题,但是它们似乎都没有帮助我:

我有一个带有几个元素的灯箱。 我可以使用XPath找到并访问所有这些元素,除了ONE。

这些是项目:
文字标题:没问题
正文:没问题 输入栏:没问题
正文:没问题 正文:没问题 按钮(上传文件):这对于找到Selenium来说似乎是不可能的 按钮(取消):没问题
按钮(发送):没问题

所有元素的XPath:

.//*[@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]

问题在于:

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

据我所知,它没有理由与其他元素(文本字段,按钮,文本)不同?

我正在通过隐式等待来访问所有这些元素,以确保它们在继续之前已经全部加载。

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

来自GCDriver(Selenium Driver)课程:

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

现在,如上所述,这适用于所有其他元素,以及直接访问它们。为此,等待超时使用WebDriverTimeoutEsception:

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

当然,尝试使用.Click()访问按钮也会失败:

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)

这是元素的html代码:

<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>

我已经尝试了其他一些获取元素的方法,但由于这是非常(imo)“混乱”的HTML,没有唯一的ID或好的类名,我一直无法弄清楚如何。

它真的让我感到烦恼,我无法通过XPath找到它。页面上有8个元素,全部可见且可访问,但使用Selenium无法找到这个元素。

元素在那里;当Selenium运行它时,我可以手动点击页面上的按钮。

更新: 我也尝试使用.Enabled而不是.Displayed。结果相同。

更新2: 下面有两个答案,我必须选择一个作为“赢家”。

Shubham Jain 给出了一个答案,虽然不是我想要的确切事情,但却是一个非常好的解决方法。通过使用JavaScriptExecutor尝试单击按钮,它还会检查按钮是否可见。但是,给出的答案并没有做它试图做的事情;点击不是那么的方式。请参阅下面的解决方案,查看使用JavaScriptExectutor单击按钮的正确/可正常代码。

smit9234 的答案正是我想要做的,虽然点击不起作用。要点击按钮,在这种情况下需要JS。然而,问题是如何检查.Displayed,这适用于他从代码摘录中给出的修改后的XPath。

解决方案

根据FirePath,元素(按钮)的XPath是

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

然而,这不起作用。 Selenium根本找不到它,即使它显然在那里。

然而,这个XPath确实有效:

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

然而,它适用于.Displayed支票的reagards。它不适用于Click()。为了能够点击按钮,我开始使用Shubham Jain的代码示例并在Driver类中创建此方法,以便能够使用JavaScript(使用Selenium的JavaScriptExecutor)单击按钮:

 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();
    }

4 个答案:

答案 0 :(得分:1)

使用以下XPath: -

//input[@type='file' and contains(@data-bind,'upload: addAttachments')]

您可以使用javascriptexecutor的selenium点击按钮。它直接在页面的JS上运行。

在java中: -

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

我不太了解c#,但我相信它像

IWebElement clicks = driver.FindElement(By.Id("gbqfq"));
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("arguments[0].click();", clicks);

根据您的方便更改上述元素中的定位器。

您将在下面找到有关javascriptexecutor

的更多详细信息

https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/JavascriptExecutor.html

希望它会对你有所帮助:)。

答案 1 :(得分:1)

查看您发布的html代码段,似乎这是一个文件附件功能。根据代码段的html结构,尝试使用以下xpath:

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

然后你应该可以使用click();方法点击&#34;添加附件&#34;

我假设点击输入没有做任何事情,但你应该能够使用sendKeys();发送&#34;文件路径的方法&#34;到输入元素。

答案 2 :(得分:0)

可能是页面上看不到输入元素。您可能不会对该元素使用显示的函数,请尝试启用,如下所示。

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

如果以上操作不起作用,则尝试单击锚标记而不是输入。

答案 3 :(得分:0)

它似乎无法点击。看起来页面上有一些javascript,其中包含一个名为&#34; upload()&#34;。

的函数。

因为你的按钮上有这个

  enable: !uploading()

只是一个测试来验证这是否真的是原因,在点击之前放置一个断点。在浏览器开发工具上,在javascript文件的upload()函数中粘贴一个断点,看看它返回了什么。

如果是这种情况,您将不得不使用javascript执行程序来绕过它。