Cucumber with Protractor 是否需要回调?
Does Cucumber with Protractor need the callback?
我正在尝试了解 The WebDriver Control Flow 的确切工作原理。
根据链接文档 (https://github.com/angular/protractor/blob/master/docs/control-flow.md) jasmine 中不需要回调方法/调用:
Protractor adapts Jasmine so that each spec automatically waits until the control flow is empty before exiting.
但是,我不得不用黄瓜。我正在使用此处描述的库 protractor-cucumber-framework
:https://github.com/angular/protractor/blob/master/docs/frameworks.md#using-cucumber
它运行良好,但出于某种原因,当我跳过回调变量时它比当我尝试使用它时效果更好。例如,此代码失败:
this.Given(/^the login page is active$/, function (callback) {
browser.get('/').then(callback);
});
有错误...
TypeError: text.split is not a function
[launcher] Process exited with error code 1
另一方面,此代码按我希望的方式工作,黄瓜/量角器似乎在等待页面加载,然后再执行其他功能:
me.Given(/^the login page is active$/, function () {
browser.get('/');
});
但是我找不到任何文档来确认我真的可以省略回调函数。
目前我尝试测试的页面没有使用 Angular,因此我的配置文件中有以下代码:
onPrepare: function() {
browser.ignoreSynchronization = true;
}
Protractor 在底层使用了 WebDriverJS。 WebDriverJS 使用一个 promise 管理器来对它的命令进行排队。这是他们维基页面的一些摘录 here
Internally, the promise manager maintains a call stack. Upon each turn
of the manager's execution loop, it will pull a task to execute from
the queue of the top-most frame. Any commands scheduled within the
callback of a previous command will be scheduled in a new frame,
ensuring they run before any tasks previously scheduled. The end
result is that if your test is written-in line, with all callbacks
defined by function literals, commands should execute in the order
they are read vertically on the screen. For example, consider the
following WebDriverJS test case:
driver.get(MY_APP_URL);
driver.getTitle().then(function(title) {
if (title === 'Login page') {
driver.findElement(webdriver.By.id('user')).sendKeys('bugs');
driver.findElement(webdriver.By.id('pw')).sendKeys('bunny');
driver.findElement(webdriver.By.id('login')).click();
}
});
driver.findElement(webdriver.By.id('userPreferences')).click();
可以使用 !WebDriver 的 Java API 重写此测试用例,如下所示:
driver.get(MY_APP_URL);
if ("Login Page".equals(driver.getTitle())) {
driver.findElement(By.id("user")).sendKeys("bugs");
driver.findElement(By.id("pw")).sendKeys("bunny");
driver.findElement(By.id("login")).click();
}
driver.findElement(By.id("userPreferences")).click();
现在回到您的问题,因为您在步骤中省略了 callback
,所以 Cucumber 会将您的测试代码视为同步代码。请参阅文档 here。由于 protractor/WebdriverJS 以上述方式处理 promise 管理器,因此一切都按预期工作。
至于您在使用 callback
时遇到的错误,我不确定。我做的和你做的完全一样。参见 here。我正在使用黄瓜 ^0.9.2
。可能是你的cucumber版本有问题
附带说明一下,我发现您可以 return 承诺而不是使用回调让黄瓜知道您已完成执行。所以像这样的东西也可以工作(假设你使用的是 ^0.9.2
)。我测试了,
me.Given(/^the login page is active$/, function () {
return browser.get('/');
});
我正在尝试了解 The WebDriver Control Flow 的确切工作原理。
根据链接文档 (https://github.com/angular/protractor/blob/master/docs/control-flow.md) jasmine 中不需要回调方法/调用:
Protractor adapts Jasmine so that each spec automatically waits until the control flow is empty before exiting.
但是,我不得不用黄瓜。我正在使用此处描述的库 protractor-cucumber-framework
:https://github.com/angular/protractor/blob/master/docs/frameworks.md#using-cucumber
它运行良好,但出于某种原因,当我跳过回调变量时它比当我尝试使用它时效果更好。例如,此代码失败:
this.Given(/^the login page is active$/, function (callback) {
browser.get('/').then(callback);
});
有错误...
TypeError: text.split is not a function
[launcher] Process exited with error code 1
另一方面,此代码按我希望的方式工作,黄瓜/量角器似乎在等待页面加载,然后再执行其他功能:
me.Given(/^the login page is active$/, function () {
browser.get('/');
});
但是我找不到任何文档来确认我真的可以省略回调函数。
目前我尝试测试的页面没有使用 Angular,因此我的配置文件中有以下代码:
onPrepare: function() {
browser.ignoreSynchronization = true;
}
Protractor 在底层使用了 WebDriverJS。 WebDriverJS 使用一个 promise 管理器来对它的命令进行排队。这是他们维基页面的一些摘录 here
Internally, the promise manager maintains a call stack. Upon each turn of the manager's execution loop, it will pull a task to execute from the queue of the top-most frame. Any commands scheduled within the callback of a previous command will be scheduled in a new frame, ensuring they run before any tasks previously scheduled. The end result is that if your test is written-in line, with all callbacks defined by function literals, commands should execute in the order they are read vertically on the screen. For example, consider the following WebDriverJS test case:
driver.get(MY_APP_URL);
driver.getTitle().then(function(title) {
if (title === 'Login page') {
driver.findElement(webdriver.By.id('user')).sendKeys('bugs');
driver.findElement(webdriver.By.id('pw')).sendKeys('bunny');
driver.findElement(webdriver.By.id('login')).click();
}
});
driver.findElement(webdriver.By.id('userPreferences')).click();
可以使用 !WebDriver 的 Java API 重写此测试用例,如下所示:
driver.get(MY_APP_URL);
if ("Login Page".equals(driver.getTitle())) {
driver.findElement(By.id("user")).sendKeys("bugs");
driver.findElement(By.id("pw")).sendKeys("bunny");
driver.findElement(By.id("login")).click();
}
driver.findElement(By.id("userPreferences")).click();
现在回到您的问题,因为您在步骤中省略了 callback
,所以 Cucumber 会将您的测试代码视为同步代码。请参阅文档 here。由于 protractor/WebdriverJS 以上述方式处理 promise 管理器,因此一切都按预期工作。
至于您在使用 callback
时遇到的错误,我不确定。我做的和你做的完全一样。参见 here。我正在使用黄瓜 ^0.9.2
。可能是你的cucumber版本有问题
附带说明一下,我发现您可以 return 承诺而不是使用回调让黄瓜知道您已完成执行。所以像这样的东西也可以工作(假设你使用的是 ^0.9.2
)。我测试了,
me.Given(/^the login page is active$/, function () {
return browser.get('/');
});