使用node.js selenium异步的页面对象模式

时间:2016-03-04 16:21:48

标签: javascript node.js asynchronous selenium-webdriver

我很难尝试使用node.js调整异步。我在使用selenium-webdriver和页面对象模式时遇到了一个问题。我觉得在进行自动化测试时,某些事情必须是同步的,否则你的测试会因为在插入数据之前单击按钮而失败。我遇到了类似的问题。我想添加一名员工,然后搜索该员工,但在添加员工之前,员工的搜索正在执行。

var employee = new Employee('grimlek', 'Charles', 'Sexton', 'TitleTitle',
    'Upper Management', 'Company Admin', 'Contractor', '-7', 'Remote',
    '05212016', '3369407787', '3368791234', 'charles@example.com',
    'charles.sexton', 'Skype', 'abcdefgh');

driver.get('https://website.com/login')
.then(function() {
     //This behaves as intended
     loginPage.login('company.admin', 'password') })
.then(function() {
      //Add employee
      employeePage.addEmployee(employee) })
.then(function() {
     //Search for employee after employee is added 
     employeePage.searchEmployee(employee)});

EmployeePage对象

var EmployeePage = function (driver) {

this.addEmployee = function (employee) {
    driver.findElement(webdriver.By.css('button[class=\'btn btn-default\']')).then(function (element) {
        //
        //Search employee function is done before the line below this
        //
        element.click();
    }).then(function () {
        setTimeout(function () {
            driver.findElement(webdriver.By.id('employee_username')).then(function (element) {
                element.sendKeys(employee.username);
            });

            driver.findElement(webdriver.By.id('employee_first_name')).then(function (element) {
                element.sendKeys(employee.firstName);
            });

            driver.findElement(webdriver.By.id('employee_last_name')).then(function (element) {
                element.sendKeys(employee.lastName);
            });

            driver.findElement(webdriver.By.id('employee_title_id')).then(function (element) {
                element.sendKeys(employee.title);
            });

            driver.findElement(webdriver.By.id('employee_role')).then(function (element) {
                element.sendKeys(employee.role);
            });
        }, 5000);
    });
//
//
//Search employee should occur when the thread leaves the function
//
};

this.searchEmployee = function (employee) {
    driver.findElement(webdriver.By.css('input[class=\'form-control ng-pristine ng-valid\']')).then(function(element) {
       element.sendKeys(employee.firstName + ' ' + employee.lastName); 
    });
};

};

module.exports = EmployeePage;

我知道searchEmployee和addEmployee函数都没有返回一个promise,我试图用.then函数链接它们。我确实认为这是我的问题,但我需要帮助它应该如何完成,而不是我如何装备它。我应该使用回调吗?我已经解决了这个问题,现在已经进行了四个小时,我已经尝试使用谷歌搜索和研究各种主题。如果我没有提供足够的代码,请告诉我,我将提供一个简化的可运行示例。

2 个答案:

答案 0 :(得分:1)

值得称赞的目标是使每个测试独立。如果对应用程序进行了更改(例如,错误修复),则只需要执行受影响的测试。此外,它使得网格可以想象。

但这在实践中很难实现。您的测试必须包括满足先决条件所需的所有测试。

Cucumber包含包含方案的功能文件每个方案都是一个测试。方案按照它们在要素文件中列出的顺序执行。因此,组织事物的一种方法是在测试之前将所有必备方案包括在特征文件中。您可以在Feature语句之前添加tag(s),以便在执行该标记时运行整个特征文件。也许第一个场景将数据库(的一个子集)重置为已知状态。

诀窍是在多台机器上并行运行功能。如果将这些多个客户端指向同一服务器,请注意这些功能不应创建或更新在服务器写入数据库时​​可能发生冲突的重叠实体。例如。 "你是什么意思用户' tom'已经存在?"每个功能都需要创建一个唯一的用户名。

答案 1 :(得分:0)

使用黄瓜的方法是为每个单独的操作划分步骤。

例如:

remote

在上述情况下,对于步骤Given I am on XYZ Form And I provide all form details ,您将在步骤定义中包含所有字段,并在单步定义中开始填写字段,例如姓名,姓氏,地址。

除此之外,我们应该为每个单独的字段划分步骤,如:

And I provide all form details

然后我们将编写3步定义,当然将按顺序运行。

您可能会觉得打字工作增加了,并且步骤定义不必要地增加了,但这实际上会帮助您从应用程序本身删除字段时,您只需要从将来的文件中删除相关步骤。 您可以通过仅对功能文件中的某个步骤进行注释,轻松测试字段验证。 并且您的代码将更容易维护,因为每个步骤都是独立工作的。

当然,顺序工作将会实现。