Selenium으로 테스트 할 웹 애플리케이션이 있습니다. 페이지로드시 많은 JavaScript가 실행됩니다.
이 JavaScript 코드는 잘 작성되지 않았지만 아무것도 변경할 수 없습니다. 따라서 findElement()
메서드 를 사용하여 요소가 DOM에 나타날 때까지 기다리는 것은 옵션이 아닙니다.
페이지가로드 될 때까지 기다리기 위해 Java에서 일반 함수를 만들고 싶습니다. 가능한 해결책은 다음과 같습니다.
- WebDriver에서 JavaScript 스크립트를 실행하고 그 결과를
document.body.innerHTML
문자열 변수에 저장합니다body
. - 비교]
body
의 이전 버전으로 변수를body
. 같으면 카운터 증가를 설정하고notChangedCount
그렇지 않으면notChangedCount
0으로 설정 합니다. - litte 시간을 기다립니다 (예 : 50ms).
- 페이지가 일정 시간 동안 (예 : 500ms) 변경되지
notChangedCount >= 10
않은 경우 루프를 종료하고 그렇지 않으면 첫 번째 단계로 루프합니다.
이것이 유효한 해결책이라고 생각하십니까?
답변
누군가가 일반적이고 항상 적용 가능한 대답을 실제로 알고 있다면 그것은 오래 전에 모든 곳 에서 구현되었을 것이며 우리의 삶을 훨씬 더 쉽게 만들 것입니다.
할 수있는 일이 많지만 모든 일에는 문제가 있습니다.
-
애쉬 윈 프라 부 말했듯이 당신이 잘 스크립트를 알고있는 경우에, 당신의 행동을 관찰하고에 그 변수의 일부를 추적 할 수 있습니다
window
또는document
등이 솔루션을하지만, 모든 사람이 아니므로 오직 제한된에서만 사용할 수 있습니다 페이지. -
HTML 코드를 관찰하고 일정 기간 동안 변경되었는지 여부를 확인하는 솔루션은 나쁘지 않습니다 (또한 직접 편집하지 않은 원본 HTML을 가져 오는 방법도 있습니다
WebDriver
).- 실제로 페이지를 주장하는 데 오랜 시간이 걸리며 테스트 시간이 크게 연장 될 수 있습니다.
- 올바른 간격이 무엇인지 결코 알 수 없습니다. 스크립트 는 500ms 이상 걸리는 큰 파일을 다운로드 할 수 있습니다. IE에서 몇 초가 걸리는 회사의 내부 페이지에는 여러 스크립트가 있습니다. 컴퓨터의 리소스가 일시적으로 부족할 수 있습니다. 즉, 바이러스 백신이 CPU를 완전히 작동시킬 수 있다고 말하면 복잡하지 않은 스크립트의 경우에도 500ms가 너무 짧을 수 있습니다.
- 일부 스크립트는 수행되지 않습니다. 그들은 약간의 지연 (
setTimeout()
)을 가지고 자신을 호출하고 반복해서 작동하며 실행될 때마다 HTML을 변경할 수 있습니다. 진지하게, 모든 “웹 2.0″페이지가 그렇게합니다. 심지어 스택 오버플로. 사용되는 가장 일반적인 방법을 덮어 쓰고이를 사용하는 스크립트를 완료된 것으로 간주 할 수 있지만 … 확실하지 않습니다. - 스크립트가 HTML 변경 이외의 작업을 수행하면 어떻게됩니까?
innerHTML
재미 뿐만 아니라 수천 가지 일을 할 수 있습니다.
-
이에 도움이되는 도구가 있습니다. 즉 , nsIWebProgressListener 및 다른 일부 와 함께 진행 리스너 입니다. 그러나 이에 대한 브라우저 지원은 끔찍합니다. Firefox는 FF4부터 지원하기 시작했으며 (아직 발전하고 있음) IE는 IE9에서 기본 지원을 제공합니다.
그리고 곧 또 다른 결함이있는 해결책을 찾을 수있을 것 같습니다. 사실은-작업을 수행하는 영원한 스크립트 때문에 “이제 페이지가 완성되었습니다”라고 말할시기에 대한 명확한 대답이 없습니다. 당신에게 가장 잘 봉사하는 것을 선택하되 단점을 조심하십시오.
답변
감사합니다 Ashwin!
제 경우에는 일부 요소에서 jquery 플러그인 실행을 기다려야합니다. 특히 “qtip”
귀하의 힌트를 바탕으로 완벽하게 작동했습니다.
wait.until( new Predicate<WebDriver>() {
public boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
}
}
);
참고 : Webdriver 2를 사용하고 있습니다.
답변
Javascript 및 jQuery가로드를 완료 할 때까지 기다려야합니다. 자바 스크립트를 실행하여 jQuery.active
is 0
및 document.readyState
is 인지 확인합니다 complete
. 이는 JS 및 jQuery로드가 완료되었음을 의미합니다.
public boolean waitForJStoLoad() {
WebDriverWait wait = new WebDriverWait(driver, 30);
// wait for jQuery to load
ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
return ((Long)executeJavaScript("return jQuery.active") == 0);
}
catch (Exception e) {
return true;
}
}
};
// wait for Javascript to load
ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
return executeJavaScript("return document.readyState")
.toString().equals("complete");
}
};
return wait.until(jQueryLoad) && wait.until(jsLoad);
}
답변
JS 라이브러리가 창에서 잘 알려진 변수를 정의 / 초기화합니까?
그렇다면 변수가 나타날 때까지 기다릴 수 있습니다. 당신이 사용할 수있는
((JavascriptExecutor)driver).executeScript(String script, Object... args)
이 조건 (예 :)을 테스트 window.SomeClass && window.SomeClass.variable != null
하고 부울 true
/을 반환합니다 false
.
이것을로 감싸고 WebDriverWait
스크립트가 반환 될 때까지 기다립니다 true
.
답변
나는 같은 문제가 있었다. 이 솔루션은 WebDriverDoku에서 저에게 효과적입니다.
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
답변
요소와 상호 작용을 시도하기 전에 페이지의 html이 안정 될 때까지 기다리기만하면 DOM을 주기적으로 폴링하고 결과를 비교할 수 있습니다. DOM이 주어진 폴링 시간 내에 동일하면 황금. 비교하기 전에 최대 대기 시간과 페이지 폴링 사이의 시간을 전달하는 것과 같은 것입니다. 간단하고 효과적입니다.
public void waitForJavascript(int maxWaitMillis, int pollDelimiter) {
double startTime = System.currentTimeMillis();
while (System.currentTimeMillis() < startTime + maxWaitMillis) {
String prevState = webDriver.getPageSource();
Thread.sleep(pollDelimiter); // <-- would need to wrap in a try catch
if (prevState.equals(webDriver.getPageSource())) {
return;
}
}
}
답변
아래 코드는 내 경우 완벽하게 작동합니다-내 페이지에는 복잡한 자바 스크립트가 포함되어 있습니다.
public void checkPageIsReady() {
JavascriptExecutor js = (JavascriptExecutor)driver;
//Initially bellow given if condition will check ready state of page.
if (js.executeScript("return document.readyState").toString().equals("complete")){
System.out.println("Page Is loaded.");
return;
}
//This loop will rotate for 25 times to check If page Is ready after every 1 second.
//You can replace your value with 25 If you wants to Increase or decrease wait time.
for (int i=0; i<25; i++){
try {
Thread.sleep(1000);
}catch (InterruptedException e) {}
//To check page ready state.
if (js.executeScript("return document.readyState").toString().equals("complete")){
break;
}
}
}