StaleElementReferenceException

StaleElementReferenceException

我一直使用 protractor / Jasmine 2遇到过时元素引用异常的问题。

我的规格:

var LoginPage = require('../pages/login_page.js');
var WelcomePage = require('../pages/welcome_page.js');

describe('Test -> testing something', function () {

    var loginPage;
    var EC = protractor.ExpectedConditions;
    var waitTimeout = 10000;

    function logIn() {
        loginPage.setUser('user');
        loginPage.setPassword('password');
        loginPage.login();
    }

    beforeEach(function () {
        browser.ignoreSynchronization = true;
        loginPage = new LoginPage();
        browser.wait(EC.presenceOf(loginPage.userLogin), waitTimeout);
        logIn();
        var welcomePage = new WelcomePage();
        browser.wait(EC.visibilityOf(welcomePage.usersButton), waitTimeout);
        welcomePage.usersButton.click();
    });

问题是,当我想单击usersButton时,StaleElementReferenceException随机发生在beforeEach函数的最后一行。
不知道为什么ExpectedCondition无法正常工作(尝试了不同的EC,例如presenceOf,elementToBeClickable等,但都没有解决问题)。

请参阅定义了usersButton的页面以供引用:
'use strict';
var WelcomePage = function () {
};

WelcomePage.prototype = Object.create({}, {
    usersButton: {
        get: function () {
            return element(by.css('#users a'));
        }
    }
});

module.exports = WelcomePage;

我认为需要一些通用的retry_mechanism来处理它,有人有类似的问题吗?

最终这样写的功能
var clickOn = function (element) {
    browser.wait(EC.visibilityOf(element), waitTimeout).then(function() {
        element.click();
    });}

像这样调用:
    clickOn(welcomePage.usersButton);

更新:
已经测试了好几次,当我在硒网格上运行测试时,我仍然在这个确切的元素上收到Stale Element异常。因此提供的解决方案不起作用...
Failed: stale element reference: element is not attached to the page document (Session info: chrome=45.0.2454.93) (Driver info: chromedriver=2.19.346078 (6f1f0cde889532d48ce8242342d0b84f94b114a1),platform=Windows NT 6.1 SP1 x86_64) (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 15 milliseconds For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html Build info: version: '2.47.1', revision: '411b314', time: '2015-07-30 03:03:16' System info: host: 'ITHFPC17', ip: '10.98.0.48', os.name: 'Windows 7', os.arch: 'x86', os.version: '6.1', java.version: '1.8.0_40' Driver info: org.openqa.selenium.chrome.ChromeDriver Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEnabled=false, chrome={userDataDir=C:\Users\SELENI~1\AppData\Local\Temp\scoped_dir2384_11396}, takesHeapSnapshot=true, databaseEnabled=false, handlesAlerts=true, hasTouchScreen=false, version=45.0.2454.93, platform=XP, browserConnectionEnabled=false, nativeEvents=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}] Session ID: 3244710644015ee170986333564ab806
Failed: Wait timed out after 10032ms

下一种方法是等到元素存在,然后再显示它,然后再单击它,否则它不能正常工作。奇怪的是,在硒网格上一切正常,但是当我尝试在本地运行测试时,出现了前面提到的异常。
exports.clickOn = function (element) {
    browser.wait(EC.presenceOf(element), waitTimeout).then(function () {
        browser.wait(EC.visibilityOf(element), waitTimeout)
    }).then(function () {
        browser.wait(EC.elementToBeClickable(element), waitTimeout)
    }).then(function () {
        element.click();
    });
};

有人知道如何处理吗? ...我被困住了。

最佳答案

通过解决等待elementToBeClickable()函数返回的 promise ,等待直到该元素有资格被单击。还要确保在click()之前完成您的操作,以便 protractor 可以按预期找到该元素。可能将所有 Action 彼此链接起来可能是一个很好的解决方案。这样就可以避免StaleElementReferenceException错误。就是这样 -

browser.wait(EC.presenceOf(loginPage.userLogin), waitTimeout).then(function(){
    logIn();
}).then(function(){
    var welcomePage = new WelcomePage();
}).then(function(){
    browser.wait(EC.elementToBeClickable(welcomePage.usersButton), waitTimeout).then(function(){
        welcomePage.usersButton.click();
    });
});

希望能帮助到你。

10-05 19:06