【问题标题】:Protractor + chrome driver: Element is not clickable at point量角器 + chrome 驱动程序:元素点不可点击
【发布时间】:2014-11-30 10:45:38
【问题描述】:

您好,我在进行基本量角器测试时遇到了一些问题。

我的设置:

  • 我使用 requirejs,所以我使用 angular.bootstrap() 初始化 angular,而不是 ng-app attr。根据量角器文档,这不支持开箱即用,但对于不涉及点击的测试似乎可以正常工作。
  • 量角器conf.json:

    "use strict";
    exports.config = {
        specs: '../E2ETests/**/*.js',
        chromeOnly: true,
        getPageTimeout: 30000,
        allScriptsTimeout: 30000
    }
    
  • 我使用了一些第三方 jquery 插件,这些插件包含在指令中,我怀疑这些可能是问题的一部分。

测试:

"use strict";
describe('When clicking should add stuff', function () {
    var ptor;
    beforeEach(function () {
        browser.get('https://localhost/myApp');
        ptor = protractor.getInstance();
    });
    it('add stuff', function () {
        // If I comment this, the test pass. 
        element(by.id('add-stuff-button')).click();
        // This does not matter fails on the line above..
        expect(browser.getTitle()).toBeDefined();
    });
});

错误:

UnknownError: unknown error: Element is not clickable at point (720, 881). Other element would         receive the click: <div class="col-md-5 col-md-offset-5">...</div>
(Session info: chrome=37.0.2062.124)
(Driver info: chromedriver=2.10.267521,platform=Windows NT 6.1 SP1 x86_64)

想法

chromedriver 确实找到了按钮,因为如果我更改 id,它会抱怨找不到元素。所以我认为问题在于按钮从其初始位置移动。由于 element(***) 函数应该等待 angular 完成,我怀疑它的第三方插件可能会干扰,因为它们可能不使用 angular api 的获取数据等。所以 angular 认为它已经完成,但是第三方插件填充和移动东西。

有什么想法吗? 如果第三方插件是问题所在,我可以以某种方式告诉 angular 第三方的事情正在发生,然后在完成后告诉它吗?

谢谢 溴 转折

【问题讨论】:

  • 如果chrome窗口太小会出现这种情况,尝试在beforeEach里面添加browser.driver.manage().window().setSize(1280, 1024);
  • 感谢起源,工作!添加为答案,我会标记它。
  • 另外,请查看this answer 了解您可以尝试的内容。

标签: angularjs protractor selenium-chromedriver


【解决方案1】:

您应该在配置文件中设置窗口大小

onPrepare: function() {
  browser.manage().window().setSize(1600, 1000);
}

【讨论】:

  • 虽然接受的答案是正确的,但这绝对是设置默认窗口大小的正确方法。
  • 更改了对此的答案,因为它似乎是更合适的解决方案。
  • 这是对所有配置的完美检查。
  • 将这些添加到 protractor.conf.js 中:exports.config = { capabilities: { 'browserName': 'chrome', 'chromeOptions': {'args': ['--window-size =1690,1000'] } } }
  • 我似乎遇到了与 OP 中描述的相同的问题,但这个答案并没有解决我的问题......在我运行 protractor conf.js 的命令行中,我得到了错误:` 失败:未知错误:元素 ... 在点 (40, 229) 处不可点击。其他元素会收到点击:
【解决方案2】:

以下对我来说效果很好:

browser.actions().mouseMove(element).click();

编辑:如果上述方法不起作用,请尝试链接 perform() 方法(我将此作为编辑建议,我尚未对其进行测试,但有人可以对其进行验证并发表评论)

browser.actions().mouseMove(element).click().perform();

【讨论】:

  • 嗨@Aman browser.actions().mouseMove(element).click();对我不起作用,所以我尝试使用 browser.actions().mouseMove(element).click().perform();,它只是悬停在元素上。没有点击。你能解决这个问题吗?
【解决方案3】:

如果chrome窗口太小会出现这种情况,请尝试在beforeEach里面添加

browser.driver.manage().window().setSize(1280, 1024);

【讨论】:

  • 你的代码有两个问题:没有必要使用 browser.driver,它会绕过量角器并在下面一层,到 webdriver 本身。您也不应该将该代码插入到 beforeEach() 块中 - 这是一种开销。
【解决方案4】:

或者干脆使用 Actions 类:

browser.actions().mouseMove(elem).click().perform();

【讨论】:

  • 嗨,劳尔,您正在发布一个老问题。你能解释一下你的解决方案比已经发布的其他解决方案更好吗?
  • Ni Noel,我最近遇到了这个问题,所以我开始寻找解决方案。我阅读了这个帖子,尝试了代码,发现actions 类还需要最后调用perform 方法。建议这种方法的人错过了包含perform() 方法的调用。对于一些没有太多 WebDriver 经验的人来说,这会有所不同。
  • 谢谢,Raul,它解决了我的用例,材料对话框关闭,然后我点击按钮进行了测试。
【解决方案5】:

有同样的问题,但与窗口大小无关,但必须等待 ngAnimation 结束。

所以我不得不等到元素可以点击。

    const msg = 'Waiting for animation timeout after 1s';
    const EC  = new protractor.ProtractorExpectedConditions();
    await browser.wait(EC.elementToBeClickable(model.elements.button.checkCompliance), 1000, `${msg} panel`);
    await model.elements.button.checkCompliance.click();

@note - 我正在使用 async/await 节点 8 功能,您也可以将其转换为常规 Promises。 也使用ProtractorExpectedConditions 而不是ExpectedConditions see documentation

【讨论】:

    【解决方案6】:

    也许它不适用于您的情况,但我遇到了同样的问题,并且根据Milena 的回答,我一直在寻找另一个隐藏我的按钮的元素(在我的情况下,下拉菜单中的我的屏幕右上角)。

    这似乎是 browsersync 发送的 Connected to Browser Sync 通知消息,由 Gulp 启动。消息在短时间内消失了,但在我的 onClick() 调用之后。

    为了删除通知,在我的 gulpfile 中,我在初始化 browsersync 时添加了 notify: false 参数:

    browserSync.init(files, {
        server: {
            baseDir: "dist",
            index: "index.html"
        },
        notify: false
    });
    

    【讨论】:

      【解决方案7】:

      我通过使用浏览器时间睡眠来解决这个问题。

      browser.driver.sleep(3000)
      

      在点击按钮之前

      【讨论】:

      • 睡眠不是最好的解决方案,因为 Protractor 为您提供了等待元素显示/可点击的机制。如果动画在 500 毫秒内完成,为什么要等待 3 秒?只等待必要的,而不是更多。
      【解决方案8】:

      您可以通过量角器配置文件(例如protractor.conf.jsconfig.js)定义所需的屏幕分辨率,以获得一致的测试行为。

      以 Chrome 浏览器为例:

      exports.config = {
        specs: [
          // ...
        ],
        capabilities: {
          browserName: 'chrome',
          chromeOptions: {
            args: [
              '--window-size=1600,900',
              '--headless'
            ]
          }
        }
        // ...
      }
      

      说明

      • window-size 参数将启动具有 1600 x 900 窗口的 Chrome。
      • headless 将启动无头 Chrome,即使您的屏幕分辨率低于该尺寸,您也可以使用指定的窗口大小(1600 x 900)运行测试。

      您可能需要两种配置,一种用于始终拥有高分辨率屏幕的开发人员(没有无头模式),另一种用于构建服务器(无头模式),其中屏幕分辨率有时是个谜,可能低于您的应用程序的分辨率/test 是专为。 Protractor 配置文件是javascript,可以扩展以避免代码重复。

      【讨论】:

        【解决方案9】:

        我遇到了同样的错误,纯粹调整屏幕尺寸并没有为我解决这个问题。

        经过进一步检查,似乎另一个元素遮住了按钮,因此 Selenium 测试失败,因为没有(也不能)单击按钮。也许这就是为什么调整屏幕尺寸可以解决某些问题的原因?

        解决我的问题是移除另一个元素(然后调整它的位置)。

        【讨论】:

          【解决方案10】:

          这比指定窗口大小更有效,以防您需要在多个显示器上运行测试。

          browser.manage().window().maximize();

          【讨论】:

            【解决方案11】:

            其他方式,你可以试试这个:

            this.setScrollPage = function (element) {
            
                function execScroll() {
                    return browser.executeScript('arguments[0].scrollIntoView()',
                        element.getWebElement())
                }
            
                browser.wait(execScroll, 5000);
                element.click();
            };
            

            【讨论】:

              【解决方案12】:

              您也可以尝试关闭您可能正在使用的任何调试工具。我正在使用 Laravel 和调试栏,必须将 APP_DEBUG 设置为 false。

              【讨论】:

                【解决方案13】:

                来自Gal Malgarit的回答,

                您应该在配置文件中设置窗口大小

                onPrepare: function() {
                  browser.manage().window().setSize(1600, 800);
                }
                

                如果它仍然不起作用,您应该滚动到元素的位置

                browser.executeScript('window.scrollTo(720, 881);');
                element(by.id('add-stuff-button')).click();
                

                【讨论】:

                  【解决方案14】:

                  请注意,这有时是由顶部导航栏或底部导航栏/cookie 警告栏覆盖元素引起的。使用 angular 2,单击时它会滚动,直到元素仅在页面上。这意味着当向下滚动点击某些东西时,如果有底部导航,那么这将阻碍点击。同样,向上滚动时,它可以被顶部导航覆盖。

                  现在,为了避免向上滚动,我使用以下内容:

                  browser.refresh();
                  browser.driver.sleep(3000);
                  

                  我确保在测试开始之前通过单击关闭底部栏来移除它。

                  【讨论】:

                    【解决方案15】:

                    这意味着元素不在可见区域内。有几种方法可以解决这个问题:

                    1. 不管可见性都强行点击元素
                    await browser.executeScript('arguments[0].click();', $element.getWebElement());
                    
                    1. 滚动到该元素,然后单击
                    await browser.executeScript(`arguments[0].scrollIntoView({block: "center"});`, $element.getWebElement());
                    await $element.click()
                    
                    1. 测试前最大化浏览器窗口的工作区域
                    beforeAll(async () => await browser.driver
                      .manage()
                      .window()
                      .setSize(1920, 1080)
                    );
                    

                    【讨论】:

                      猜你喜欢
                      • 2012-11-19
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-12-10
                      • 1970-01-01
                      • 1970-01-01
                      • 2015-03-03
                      • 1970-01-01
                      相关资源
                      最近更新 更多