Я использую Selenium 3.4 с Java. С Хромом все работает нормально. Но мне нужно использовать Firefox, а там что-то ломается.
Я автоматизирую тестирование пользовательского интерфейса Dojo, и мне нужно подождать, пока пользовательский интерфейс Dojo выполнит большую часть рендеринга. Итак, вот что я делаю, и это прекрасно работает в Chrome. Обратите внимание, что в моем коде обычно устанавливается неявное ожидание в 20 секунд.
driver.switchTo().defaultContent();
driver.switchTo().frame(driver.findElement(By.id("contentframe"))); // relying on implicit wait
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
(new WebDriverWait(driver, 120)).
until(ExpectedConditions.elementToBeClickable(By.id("some_id")));
Я упростил код, чтобы вы не видели, как неявное ожидание возвращается к 20 секундам. Когда проблема возникает, она все равно туда не попадает. WebDriverWait вызывает исключение. Исключение говорит TypeError: can't access dead object
Внутри ожидания есть соответствующее сообщение:
May 16, 2017 3:36:11 PM org.openqa.selenium.support.ui.ExpectedConditions findElement
WARNING: WebDriverException thrown by findElement(By.id:
some_id)
org.openqa.selenium.WebDriverException: TypeError: can't access dead object
Также есть некоторые ошибки JavaScript, по-видимому, от geckodriver:
JavaScript error: chrome://marionette/content/listener.js, line 1555: TypeError: can't access dead object
*************************
A coding exception was thrown and uncaught in a Task.
Full message: TypeError: can't access dead object
Full stack: find_@chrome://marionette/content/element.js:284:7
element.find/</findElements<@chrome://marionette/content/element.js:255:15
implicitlyWaitFor/</elementSearch@chrome://marionette/content/element.js:600:15
implicitlyWaitFor/<@chrome://marionette/content/element.js:627:5
implicitlyWaitFor@chrome://marionette/content/element.js:593:10
element.find/<@chrome://marionette/content/element.js:254:24
element.find@chrome://marionette/content/element.js:253:10
findElementsContent@chrome://marionette/content/listener.js:1314:19
TaskImpl_run@resource://gre/modules/Task.jsm:319:42
TaskImpl@resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction@resource://gre/modules/Task.jsm:252:14
Task_spawn@resource://gre/modules/Task.jsm:166:12
TaskImpl_handleResultValue@resource://gre/modules/Task.jsm:389:16
TaskImpl_run@resource://gre/modules/Task.jsm:327:15
TaskImpl@resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction@resource://gre/modules/Task.jsm:252:14
Task_spawn@resource://gre/modules/Task.jsm:166:12
dispatch/<@chrome://marionette/content/listener.js:186:15
*************************
*************************
A coding exception was thrown and uncaught in a Task.
Full message: TypeError: can't access dead object
Full stack: find_@chrome://marionette/content/element.js:284:7
element.find/</findElements<@chrome://marionette/content/element.js:255:15
implicitlyWaitFor/</elementSearch@chrome://marionette/content/element.js:600:15
implicitlyWaitFor/<@chrome://marionette/content/element.js:627:5
implicitlyWaitFor@chrome://marionette/content/element.js:593:10
element.find/<@chrome://marionette/content/element.js:254:24
element.find@chrome://marionette/content/element.js:253:10
findElementsContent@chrome://marionette/content/listener.js:1314:19
TaskImpl_run@resource://gre/modules/Task.jsm:319:42
TaskImpl@resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction@resource://gre/modules/Task.jsm:252:14
Task_spawn@resource://gre/modules/Task.jsm:166:12
TaskImpl_handleResultValue@resource://gre/modules/Task.jsm:389:16
TaskImpl_run@resource://gre/modules/Task.jsm:327:15
TaskImpl@resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction@resource://gre/modules/Task.jsm:252:14
Task_spawn@resource://gre/modules/Task.jsm:166:12
dispatch/<@chrome://marionette/content/listener.js:186:15
Более того, моя автоматическая обработка исключений пытается сделать снимок экрана, но это не удается с той же ошибкой. Строка кода:
File snapshotTempFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
И на этот раз вывод geckodriver:
A coding exception was thrown and uncaught in a Task.
Full message: TypeError: can't access dead object
Full stack: capture.viewport@chrome://marionette/content/capture.js:65:7
takeScreenshot@chrome://marionette/content/listener.js:1782:14
dispatch/</req<@chrome://marionette/content/listener.js:188:22
TaskImpl_run@resource://gre/modules/Task.jsm:319:42
TaskImpl@resource://gre/modules/Task.jsm:277:3
createAsyncFunction/asyncFunction@resource://gre/modules/Task.jsm:252:14
Task_spawn@resource://gre/modules/Task.jsm:166:12
dispatch/<@chrome://marionette/content/listener.js:186:15
Итак, могу ли я что-нибудь сделать, чтобы это работало правильно? И это то, что мне нужно поднять как ошибку геккодрайвера?
Единственное, что я смог найти в Google, это: https://github.com/mozilla/geckodriver/issues/614 и единственное предлагаемое решение — driver.switchTo().defaultContent()
. Это может исправить мою процедуру создания скриншотов, но элемент, которого я жду, находится внутри фрейма содержимого, поэтому я не могу использовать это исправление для ожидания.