【问题标题】:Click on pseudo element using Selenium使用 Selenium 单击伪元素
【发布时间】:2018-01-07 16:40:45
【问题描述】:

我正在尝试使用 Selenium 单击 ::after 伪元素。我意识到这不能直接通过 WebDriver 完成,但似乎无法找到使用 Javascript 的方法。

这是 DOM 的样子:

<em class="x-btn-split" unselectable="on" id="ext-gen161">
    <button type="button" id="ext-gen33" class=" x-btn-text">
        <div class="mruIcon"></div>
        <span>Accounts</span>
    </button>
    ::after
</em>

这就是上面的元素的样子。对象的左侧是 'button' 元素, :after 元素是右侧的箭头,单击时会弹出一个下拉菜单。如您所见,右侧没有任何标识符,这部分是导致此操作变得困难的部分原因。

我在 stackoverflow 中看到了这两个链接,并尝试将答案组合起来形成我的解决方案,但无济于事。

Clicking an element in Selenium WebDriver using JavaScript
Locating pseudo element in Selenium WebDriver using JavaScript

这是我的尝试之一:

string script = "return window.getComputedStyle(document.querySelector('#ext-gen33'),':before')";
IJavaScriptExecutor js = (IJavaScriptExecutor) Session.Driver;
js.ExecuteScript("arguments[0].click(); ", script);

我得到这个错误:

System.InvalidOperationException: 'unknown error: arguments[0].click is not a function
  (Session info: chrome=59.0.3071.115)
  (Driver info: chromedriver=2.30.477700 (0057494ad8732195794a7b32078424f92a5fce41),platform=Windows NT 6.1.7601 SP1 x86_64)'

我还尝试使用 Selenium 中的 Actions 类来参考左侧移动鼠标,类似于this answer。我认为这可能是因为我不知道偏移量是多少,并且文档似乎没有给出任何指示。我认为是像素??

Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).MoveByOffset(235, 15).Click().Build().Perform();

这个尝试似乎点击了某个地方,因为它没有给出错误,但我不确定在哪里。

如果有帮助,我正在尝试在 c# 中自动化 Salesforce(服务云)。

也许有人可以提供解决方案?

【问题讨论】:

  • 点击伪元素附加到的元素
  • 我们可以尝试另一种方法,例如图像识别向下箭头并单击。我们可以使用 sikuli 来完成它。我们需要下载库并使用它。Screen scr = new Screen(); Pattern Image1 = new Pattern("D:/>SikuliImages/SignupClick.png"); scr.Click(Image1, true);其中 image1 是裁剪后的下拉菜单。
  • @guest271314 我试过了,但没那么简单,然后按钮的左侧被点击了,这就是我的问题。我需要点击右侧。
  • @Jand 据我所知,不可能以编程方式将 DOM 事件分派给 CSS 伪元素或伪类。
  • @santhoshkumar 有趣的解决方案。Sikuli 网站没有列出它是用 c# 编写的。

标签: javascript c# selenium pseudo-element


【解决方案1】:

我在为 Salesforce 编写 Selenium 测试时遇到了同样的问题,并设法通过使用 Actions 直接控制鼠标来解决它。

此按钮的包装表的硬编码宽度为 250 像素,您已经发现了这一点。要定位鼠标的位置,你可以使用contextClick() 方法而不是Click(). 它模拟鼠标右键,所以它总是会打开浏览器菜单。

如果你这样做:

Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).ContextClick().Build().Perform();

您会发现鼠标移动到 WebElement 的中间,而不是左上角(我认为它也是如此)。由于元素宽度是恒定的,我们可以将鼠标向右移动250 / 2 - 1,它会起作用:) 代码:

Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).MoveByOffset(124, 0).Click().Build().Perform();

【讨论】:

    【解决方案2】:

    对于那些尝试在 Python 中执行此操作的人,解决方案如下:

    elem= driver.<INSERT THE PATH TO ELEMENT HERE> ActionChains(driver).move_to_element_with_offset(elem,249,1).click().perform()

    基本上,我在 DOM 中找到我的元素并分配给 WebElement。然后将 WebElement 作为参数传递给 move_to_element_with_offset 方法。

    我从开发者工具中获得了元素的 px 值。

    PS:使用这个 import- from selenium.webdriver.common.action_chains import ActionChains

    您可以在此处阅读有关 Action chain 类及其方法 move_to_element_with_offset 的更多信息:http://selenium-python.readthedocs.io/api.html

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      Maciej 上面的答案适用于 WebDriver,但不适用于针对 Firefox V.56 的 RemoteWebDriver (Selenium 3.12.0)。我们需要一个适用于本地和远程的解决方案。最终使用键盘快捷键调用导航菜单下拉菜单。作为一个额外的好处,这也消除了使用偏移量的需要。

      String navigationMenuDropdownShortcutKeys = Keys.chord(Keys.ESCAPE, "v");
      
      new Actions(driver)
       .sendKeys(navigationMenuDropdownShortcutKeys)
       .perform();
      

      【讨论】:

      • 能否请您解释一下 esc + v 是如何选择菜单的?如果它有效,那么它将非常有帮助。请解释一下。
      • 它确实有效 :-) 试试看。默认情况下,Salesforce 允许使用许多键盘快捷键。这只是调用组合键来下拉菜单。
      • 这是销售队伍的捷径,明白了。我的问题是笼统的,不是针对销售人员的。谢谢
      【解决方案4】:

      我将提供一种可能适用于某些场景的替代方案,至少它对我有用,并且通过 JS 脚本使用 selenium 在任何语言中都相对容易实现。

      在我的场景中,有一个 ::after 伪元素包含按钮的功能。这个按钮被包含在一个相对于它下面的另一个元素的位置中。

      所以我做了以下事情:

      1. 获取我能得到的元素,在这个问题场景中就是那个跨度。
      2. 获取元素的坐标。
      3. 计算相对于您要单击的伪元素的该元素的坐标。
      4. 点击这些坐标。

      这是我使用 perl 的代码,但我相信你可以用任何语言做同样的事情:

      my $script="
      function click_function(x, y)
      {
          console.log('Clicking: ' + x + ' ' + y);
      
          var ev = new MouseEvent('click', {
              'view': window,
              'bubbles': true,
              'cancelable': true,
              'screenX': x,
              'screenY': y
          });
      
          var el = document.elementFromPoint(x, y);
      
          el.dispatchEvent(ev);
      }
      
      var element = document.getElementById('here_put_your_id'); //replace elementId with your element's Id.
      var rect = element.getBoundingClientRect();
      var elementLeft,elementTop; //x and y
      var scrollTop = document.documentElement.scrollTop?
                     document.documentElement.scrollTop:document.body.scrollTop;
      var scrollLeft = document.documentElement.scrollLeft?            
      
          document.documentElement.scrollLeft:document.body.scrollLeft;
      elementTop = rect.top+scrollTop;
      elementLeft = rect.left+scrollLeft;
      console.log('Coordiantes: ' + elementLeft + ' ' + elementTop)
      
      click_function(elementLeft*1.88, elementTop*1.045) // here put yor relative coordiantes
          ";
          $driver->execute_script($script);
      

      【讨论】:

        【解决方案5】:

        在阅读了大量文章和博客后,我找到了确定如何在 Selenium 中检测 DOM 中的伪元素的方法。并根据特定条件验证是否存在。

        第 1 步

        找到包含伪元素的父元素的路径,并在findElement下传递,如下所示

        WebElement pseudoEle = driver.findElement(path);
        

        第 2 步

        String display = ((JavascriptExecutor)getWebDriver()).executeScript("return window.getComputedStyle(arguments[0], ':after').getPropertyValue('display');",pseudoEle).toString();
        

        在上面的代码行中,传递所需的伪代码来代替“:after”(在我的情况下,我正在寻找“after”),并且基于伪代码而改变的属性值存在或不存在(就我而言,它是“显示”)。

        注意:当伪元素出现时,javascript 代码返回“Block”,我又将其保存在 display 字段中。并根据场景使用。

        为您的案例确定正确的财产价值的步骤

        1. 检查元素。
        2. 导航到伪代码的父元素。
        3. 在样式选项卡下找出当伪代码存在和不存在时其值发生变化的字段(绿色)。

        我相信这将在很大程度上帮助您。请喜欢和支持,会鼓励我发布更多这样的解决方案。

        谢谢!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-11-24
          • 2021-12-31
          • 2017-07-25
          • 1970-01-01
          • 2016-09-05
          • 2018-05-26
          相关资源
          最近更新 更多