Недавно я столкнулся с очень странной ошибкой с nodejs & selenium-webdriver. Он выглядит связанным с nodejs event loop/prom/selenium-webdriver.selenium webdriver висит в очень простом коде javascript с обещанием.
Вкратце: звонок webdriver.get будет висеть при использовании с некоторыми promise.then
.
Во-первых, давайте посмотрим кусок яваскрипта кода, который хорошо работает:
const WebDriver = require('selenium-webdriver')
var driver = new WebDriver.Builder()
.setAlertBehavior('ignore')
.forBrowser('chrome')
.build()
function ok() {
console.log('ok: driver.get will open a browser window\n' + '\n' + ok + '\n')
driver.get('about:blank')
}
ok()
Этот код будет открыть окно браузера, который работает, как ожидалось.
Но весь следующий код покажет странное поведение.
Bug - driver.get будет висеть
после добавления фиктивного .then(() => 'test')
function bug() {
console.log('bug: `driver.get` will hang\n' + '\n' + bug + '\n')
Promise.resolve()
.then(() => 'test')
.then(() => driver.get('about:blank'))
}
FIX1 - удалить 1-й then
вызов
function fire1() {
console.log('fix1: delete the `then` call\n' + '\n' + fire1 + '\n')
Promise.resolve()
.then(() => driver.get('about:blank'))
}
fix2 - или добавить catch
вызов
function fire2() {
console.log('fix2: add a `catch` call\n' + '\n' + fire2 + '\n')
Promise.resolve()
.then(() => 'test')
.catch(e => console.error(e))
.then(() => driver.get('about:blank'))
}
Fix3 - или разрешить обещание с setTimeout
вместо решимости непосредственно
function fire3() {
console.log('fix3: resolve promise with a `setTimeout` call\n' + '\n' + fire3 + '\n')
new Promise((resolve, reject) => {
setTimeout(resolve, 0)
})
.then(() => 'test')
.then(() => driver.get('about:blank'))
}
Все вышеперечисленное кода проверяется при nodejs v6.0.0.
Есть ли кто-нибудь, встретивший эту проблему раньше? В чем причина этого?
Я подумал, что это может быть связано с циклом событий nodejs или с внедрением собственных обещаний ... но я больше не знаю, как глубоко.
Код в Gist: https://gist.github.com/zixia/77896cbd446c7282f760c60a025fee17
Github вопрос: https://github.com/SeleniumHQ/selenium/issues/2233
Очень странно. Начиная с вашей версии «Bug - driver.get will hang», будет '.then (function() {return 'test';})' исправить? –
@ Roamer-1888 no. .then (...) является причиной причиной ошибки. если вы избавитесь от '.then (...)', он будет работать так, как ожидалось. если вы добавите '.catch (...)' для сопряжения с '.then (...)', он будет работать так же, как и ожидалось. очень странно. – zixia
Кажется, что успех зависит от количества микротомов между «driver = new WebDriver.Builder() .... build()» и «driver.get ('about: blank')'. Нуль, 1 и 3 микротома впереди, все нормально, но 2 нет. Но почему это важно? –