如何在 selenium-webdriver 中禁用承诺管理器
How to disable promise manager in selenium-webdriver
如 https://code.google.com/p/selenium/wiki/WebDriverJs#Promises 中所述,selenium-webdriver
使用自动承诺管理器来避免人们必须进行重复的承诺链接。
但是,在某些情况下,promise 管理器所做的假设,即连续调用应该被链接起来是错误的,应该停用它。
例如:
var isLoaded = function (browser) {
var waitForJS = waitForElement(browser, By.css('body.js'));
var waitForMobile = waitForElement(browser, By.css('#mobile_landing_page'));
return Promise.any([waitForJS, waitForMobile]);
};
在这里我想创建一个通用函数,无论是在移动着陆页还是桌面站点上,都等到满足这两个条件中的任何一个。
承诺经理解释它的方式是
var isLoaded = function (browser) {
var waitForMobile = waitForElement(browser, By.css('#mobile_landing_page'));
var waitForJS = waitForElement(browser, By.css('body.js')).then(function () {
return waitForMobile;
});
return Promise.any([waitForJS, waitForMobile]);
};
对于非移动案例,这显然永远无法解决,因为一次只能满足其中一个。
有没有办法完全禁用承诺管理器并手动安排所有调用?
这是waitForElement
的定义
var waitForElement = function (browser, element, timeout) {
return browser.wait(until.elementLocated(element), timeout);
};
获得所需内容的最简单方法就是使用 CSS 选择器查找一个 ID 或 另一个。以下示例模拟延迟加载。我们正在寻找具有 #foo
或 #bar
的元素。所以我们使用选择器#foo, #bar
。在您的情况下,它将是 body.js, #mobile_landing_page
。这样做是最有效的方法,因为它减少了 Selenium 脚本和浏览器之间的往返次数。
var webdriver = require('selenium-webdriver');
var By = webdriver.By;
var until = webdriver.until;
var firefox = require('selenium-webdriver/firefox');
var Promise = require('bluebird').Promise;
var browser = new firefox.Driver();
browser.get("http://www.example.com");
//
// Decide randomly what we are going to be looking for
//
// This math here is probably not something to be emulated if you need
// serious randomness (e.g. crypto).
//
var flip = Math.round(Math.random(0, 1));
var id = flip ? "foo": "bar";
console.log("We'll be simulating the delayed loading of an element with id", id);
var waitForElement = function (browser, element, timeout) {
return browser.wait(until.elementLocated(element), timeout);
};
var isLoaded = function (browser) {
return waitForElement(browser, By.css("#foo, #bar"));
};
// Simulate the delayed loading of the element we are going to look for.
browser.executeScript('\
var id = arguments[0];\
setTimeout(function () {\
var el = document.createElement("div");\
el.id = id;\
document.body.appendChild(el);\
}, 1000);\
', id);
isLoaded(browser);
browser.quit();
我知道这已经过时了,但是对于 google 登陆这里 in/after 2017 的人来说,试试这个:
Promise.any
是一个蓝鸟结构。它returns首先要解决。
如果两者都想等待,正确的方法是Promise.all
。
尝试这样的事情:
var isLoaded = function (browser) {
var waitForJS = waitForElement(browser, By.css('body.js'));
var waitForMobile = waitForElement(browser, By.css('#mobile_landing_page'));
return Promise.all([waitForJS, waitForMobile]);
};
// Then use like this:
isLoaded(browser)
.then((elemCheck) => {
const hasBodyJsTag = elemCheck[0]
const hasMobileTag = elemCheck[1]
console.log('Elem Status:', elemCheck)
})
如 https://code.google.com/p/selenium/wiki/WebDriverJs#Promises 中所述,selenium-webdriver
使用自动承诺管理器来避免人们必须进行重复的承诺链接。
但是,在某些情况下,promise 管理器所做的假设,即连续调用应该被链接起来是错误的,应该停用它。
例如:
var isLoaded = function (browser) {
var waitForJS = waitForElement(browser, By.css('body.js'));
var waitForMobile = waitForElement(browser, By.css('#mobile_landing_page'));
return Promise.any([waitForJS, waitForMobile]);
};
在这里我想创建一个通用函数,无论是在移动着陆页还是桌面站点上,都等到满足这两个条件中的任何一个。
承诺经理解释它的方式是
var isLoaded = function (browser) {
var waitForMobile = waitForElement(browser, By.css('#mobile_landing_page'));
var waitForJS = waitForElement(browser, By.css('body.js')).then(function () {
return waitForMobile;
});
return Promise.any([waitForJS, waitForMobile]);
};
对于非移动案例,这显然永远无法解决,因为一次只能满足其中一个。
有没有办法完全禁用承诺管理器并手动安排所有调用?
这是waitForElement
var waitForElement = function (browser, element, timeout) {
return browser.wait(until.elementLocated(element), timeout);
};
获得所需内容的最简单方法就是使用 CSS 选择器查找一个 ID 或 另一个。以下示例模拟延迟加载。我们正在寻找具有 #foo
或 #bar
的元素。所以我们使用选择器#foo, #bar
。在您的情况下,它将是 body.js, #mobile_landing_page
。这样做是最有效的方法,因为它减少了 Selenium 脚本和浏览器之间的往返次数。
var webdriver = require('selenium-webdriver');
var By = webdriver.By;
var until = webdriver.until;
var firefox = require('selenium-webdriver/firefox');
var Promise = require('bluebird').Promise;
var browser = new firefox.Driver();
browser.get("http://www.example.com");
//
// Decide randomly what we are going to be looking for
//
// This math here is probably not something to be emulated if you need
// serious randomness (e.g. crypto).
//
var flip = Math.round(Math.random(0, 1));
var id = flip ? "foo": "bar";
console.log("We'll be simulating the delayed loading of an element with id", id);
var waitForElement = function (browser, element, timeout) {
return browser.wait(until.elementLocated(element), timeout);
};
var isLoaded = function (browser) {
return waitForElement(browser, By.css("#foo, #bar"));
};
// Simulate the delayed loading of the element we are going to look for.
browser.executeScript('\
var id = arguments[0];\
setTimeout(function () {\
var el = document.createElement("div");\
el.id = id;\
document.body.appendChild(el);\
}, 1000);\
', id);
isLoaded(browser);
browser.quit();
我知道这已经过时了,但是对于 google 登陆这里 in/after 2017 的人来说,试试这个:
Promise.any
是一个蓝鸟结构。它returns首先要解决。
如果两者都想等待,正确的方法是Promise.all
。
尝试这样的事情:
var isLoaded = function (browser) {
var waitForJS = waitForElement(browser, By.css('body.js'));
var waitForMobile = waitForElement(browser, By.css('#mobile_landing_page'));
return Promise.all([waitForJS, waitForMobile]);
};
// Then use like this:
isLoaded(browser)
.then((elemCheck) => {
const hasBodyJsTag = elemCheck[0]
const hasMobileTag = elemCheck[1]
console.log('Elem Status:', elemCheck)
})