Selenium WebDriver가 현재 보이지 않는 요소를 클릭하도록 강제하는 방법은 무엇입니까?


99

FirefoxDriver와 함께 Selenium 2 Java API를 사용하고 있습니다. 양식을 채울 때 양식 입력에 따라 페이지에 확인란이 추가됩니다.

Selenium을 사용하여 해당 확인란을 클릭하는 것을 시뮬레이션하고 싶습니다. 요소는 일반 브라우저에서 볼 수 있고 사용할 수 있지만 셀레늄은 요소가 보이지 않는다고 주장합니다.

"Element is not currently visible and so may not be interacted with"

셀레늄이 요소의 보이지 않는 상태를 무시하도록 할 수 있습니까? Selenium이 보이지 않는 요소와 상호 작용하게하려면 어떻게해야합니까?


어떤 브라우저를 사용하고 있습니까? 최종 사용자가 상호 작용할 수 없기 때문에 비활성화되거나 표시되지 않는 요소와 상호 작용할 수 없습니다. 제가 문제를 진단 해 보도록하려면 테스트 코드와 페이지 소스를 제공해야합니다.
Ardesco

답변:


102

Selenium은 다음 기준에 따라 요소가 표시되는지 여부를 결정합니다 (DOM 검사기를 사용하여 요소에 적용되는 CSS를 결정하고 계산 된 스타일을 확인하세요).

  • 가시성! = 숨김
  • display! = none (모든 상위 요소에 대해서도 확인 됨)
  • 불투명도! = 0 (요소 클릭시 선택되지 않음)
  • 높이와 너비가 모두> 0
  • 입력의 경우 속성 유형! = 숨김

요소가 해당 기준 중 하나와 일치합니다. 요소의 스타일을 변경할 수없는 경우 다음은 자바 스크립트로 강제로 수행 할 수있는 방법입니다 (Selenium2 API라고 말 했으므로 WebDriver를 가정합니다).

((JavascriptExecutor)driver).executeScript("arguments[0].checked = true;", inputElement);

그러나 그것은 자바 스크립트 이벤트를 발생시키지 않을 것입니다. 해당 입력에 대한 변경 이벤트에 의존하는 경우에도 발생해야합니다 (이를 수행하는 많은 방법, 해당 페이지에로드 된 자바 스크립트 라이브러리를 사용하는 것이 가장 쉽습니다).

가시성 검사의 출처-

https://github.com/SeleniumHQ/selenium/blob/master/javascript/atoms/dom.js#L577

이것을 정의하는 WebDriver 사양-

https://dvcs.w3.org/hg/webdriver/raw-file/tip/webdriver-spec.html#widl-WebElement-isDisplayed-boolean


1
조건 목록에 대한 소스 (또는 표준 링크)가 있습니까?
mjs

2
Javascript를 읽을 수있는 한 bot.dom.isShown 메소드가 가시성을 결정합니다. code.google.com/p/selenium/source/browse/trunk/javascript/atoms/…
lukeis

여기서 inputElement는 무엇입니까? 아래 코드를 실행합니다. WebElement inputElement = driver.findElement (By.xpath (PASSWORD_PATH)); ((JavascriptExecutor) driver) .executeScript ( "arguments [0] .checked = true;", inputElement); 그러나 도움말은 없습니다 inputElement.sendKeys (password);
Deepak Goel

2
@NIleshSharma python에는 드라이버 객체 자체에 직접 execute_script 메소드가 있습니다. driver.execute_script (...)
lukeis

1
@TunaBum에 의해 게시 소스 링크가 변경되었습니다 code.google.com/p/selenium/source/browse/javascript/atoms/...
Shepmaster

27

때때로 이것은 검색하려는 동일한 속성을 가진 페이지에 여러 요소가 있고 "잘못된 요소와 대화"하고 있음을 의미합니다.

요소를 : id 또는 : name (또는 : class)으로 고유하게 식별 할 수없는 경우 까다로울 수 있습니다.

때때로 : xpath로 요소를 검색하는 것이 도움이되며 어떤 경우에는 실용적이지 않습니다.

이러한 경우 기준과 일치하는 모든 요소를 ​​가져와 색인별로 올바른 요소를 참조해야 할 수 있습니다. 더럽지 만 작동합니다.

Ruby on Rails 앱의 Selenium / Watir를 사용하고 있으므로 제 경우에는 다음과 같은 예가 있습니다.

browser = Watir::Browser.new(:firefox, :profile => "default")       
browser.goto("http://www.google.com/analytics")
# login
browser.divs(:text, "+ New Property").last.click

도움이 되었기를 바랍니다.


dom 요소에 id를 추가하여 나를 위해 수정했습니다
naoru

나는 같은 문제가 있었고 XPath를 조정하여 고유 한 요소를 구별 할 수 있도록했습니다.
JohnL

나는 같은 문제가 있었다. 일치 수를 계산하기 위해 findElements () 호출을 변경했으며 일치하는 요소가 하나 더 있습니다. 감사!
Aries

나를 위해 너무 많이. 선택 기준이 상호 작용하고 있다고 생각하는 요소에 충분히 구체적인지 항상 확인하십시오. 여러 번 나는 두 가지 요소를 가지고 있었고 하나는 숨겨져 있으며이 오류를 제공합니다.
Chris

14

비슷한 문제가 있었지만 뷰포트에 표시되지 않는 요소와 관련이 있습니다. 스크린 샷을 찍고 브라우저 창이 너무 좁아서 요소를 볼 수 없다는 것을 깨달았습니다. 나는 이것들 중 하나를했고 효과가 있었다.

driver.maximize_window()

참조 : WebDriver.maximize_window ()


7

또는 Selenium Action Class를 사용하여 사용자 상호 작용을 시뮬레이션 할 수 있습니다.

    WebDriver = new FirefoxDriver();

    WebElement menu = driver.findElement(By.xpath("")); // the triger event element

    Actions build = new Actions(driver); // heare you state ActionBuider
    build.moveToElement(menu).build().perform(); // Here you perform hover mouse over the needed elemnt to triger the visibility of the hidden
    WebElement m2m= driver.findElement(By.xpath(""));//the previous non visible element
    m2m.click();

7

보이는 요소가 보이지 않는 것으로 인식되는 또 다른 경우가 있습니다.

  • 요소가 CSS로 변환 된 경우
  • 요소의 부모 요소가 CSS로 변환 된 경우

상호 작용하지 않으려는 요소가 CSS로 변환되었는지 확인하려면 CHROME에서 다음을 수행하십시오.

  1. 열린 검사관
  2. 흥미로운 요소 (또는 상위 요소, 아마도 div 요소) 찾기
  3. '계산 됨'탭을 선택합니다.
  4. 매개 변수가있는 경우 : webkit-transform : matrix (...) 이는 요소가 CSS로 변환되었음을 의미하며 셀레늄 2에서 보이는 요소로 인식되지 않을 수 있습니다.


2

인터넷 익스플로러 9에서 셀레늄 2와 같은 문제가 있었지만 수정이 정말 이상합니다. 내 양식 내부의 입력을 클릭 할 수 없었습니다-> 셀레늄 반복은 보이지 않습니다.

내 양식에 곡선 그림자가있을 때 발생했습니다.-> http://www.paulund.co.uk/creating-different-css3-box-shadows-effects : 콘크리트 "효과 2"에서

이 의사 요소 솔루션이 셀레늄 테스트를 중단 한 이유와 방법을 모르겠지만 저에게 효과적입니다.


2

Selenium은 사용자 상호 작용을 모방하도록 설계 되었기 때문에 사용자가 일반적으로 액세스 할 수없는 요소에 액세스 / 변경을 강제 할 수 없습니다.

이 오류가 발생하면 다음 사항을 확인하십시오.

  • 요소는 뷰포트에서 볼 수 있습니다 (예를 들어, 사용 webdriver있는 현재 창을 최대화하려고 maximize()에서 Node.js를 , maximize_window()파이썬에서)
  • 요소가 동일한 선택기 아래에 두 번 표시되지 않고 잘못된 요소를 선택하고 있습니다.
  • 요소가 숨겨져있는 경우 표시되도록 설정하고
  • 당신이 제한에도 불구하고 숨겨진 요소의 액세스 / 변경 값을 원하는 경우 다음 (예를 들어, 그것을 위해 자바 스크립트 사용 executeScript()Node.js를 , execute_script()파이썬을).

1
나는 Selenium이 이렇게 엄격하게 설계되었는지 전혀 몰랐습니다. 일반적인 의미에서 실제로 자동화 도구가 아닌 자동화 된 사용자 상호 작용 도구가 아닌 것 같습니다. 내가 생각하기에 약간 의미가 있습니다. 명확히 해주셔서 감사합니다!
Daniel Lidström

1

ror 프로젝트에서 capybara를 사용하는 동안 다음을 추가하여이 오류를 해결합니다.

Capybara.ignore_elements = true

features/support/env.rb.


1

나는 대기 요소 표시 속성 으로이 오류를 해결합니다.

waitFor() { element.displayed }

이 페이지의 모든 답변 중 이것이 Bootstrap Modal 대화 상자에서 내 문제를 해결 한 것입니다. @Suat Keskin 감사합니다!
alastairs

1

다음과 같은 템플릿의 링크로 부트 스트랩 글 리피 콘이있는 장고 사이트에서 기능 테스트를 위해 셀레늄을 사용하여 ElementNotVisibleException 예외가 발생합니다.

<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger"></span></a>

기능 테스트 중에 부트 스트랩 스타일이로드되지 않은 다음 이러한 링크를 클릭하려고하면 ElementNotVisibleException이 발생합니다. 다음 과 같이 태그에 공백추가하기 만하면 클릭 할 수 있습니다 .

<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger">&nbsp;</span></a>

1

이 페이지에는 좋은 답변이 많이 있습니다.

  1. 저는 일반적으로 maximize.window ()로 시작합니다. 실제로는 드라이버 팩토리 또는 드라이버를 초기화하는 곳에서이 작업을 수행합니다. 이것은 기본적으로 항상 수행됩니다.
  2. 일반적으로 자바 스크립트 지연으로 인해 요소를 기다립니다.

둘 다 위에서 다양한 세부 사항에서 논의됩니다. 내가 보지 못한 대답은 ScrollToElement였습니다. 요소 목록을 처리하는 동안 처리하는 동안 더 많은 요소, 확인란을 만드는 것처럼 들립니다. 이로 인해 목록의 요소가 보이는 페이지 밖으로 이동할 수 있습니다. 때때로 육안으로 요소를 볼 수 있지만 클릭 할 수 없습니다. 목록을 처리 할 때 때때로 스크롤링을 중단해야합니다.

  • 중단 점을 설정하고 사용중인 요소가 창 가장자리, 상단 / 하단 오른쪽 / 왼쪽에 있는지 확인합니다. 때때로 이런 경우 셀레늄을 통해 얻을 수 없지만 마우스로 수동으로 클릭 할 수 있습니다.

이것을 실행하기 때문에 PageScroll.java를 만들고 거기에 스크롤 스크립트를 넣었습니다. 다음은이 클래스의 몇 가지 메서드입니다.

public static void scrollToTop(WebDriver driver) {
      ((JavascriptExecutor) driver)
        .executeScript("window.scrollTo(0,0)");
    }

    public static void scrollToBottom(WebDriver driver) {
      ((JavascriptExecutor) driver)
        .executeScript("window.scrollTo(0, document.body.scrollHeight)");
    }

    public static void scrollToElementTop(WebDriver driver, WebElement element) {
      ((JavascriptExecutor) driver).executeScript(
        "arguments[0].scrollIntoView(true);", element);
    }

    public static void scrollToElementBottom(WebDriver driver, WebElement element) {
      ((JavascriptExecutor) driver).executeScript(
        "arguments[0].scrollIntoView(false);", element);
    }

더 많은 예제 는 Selenium 을 사용 하여보기로 요소 스크롤을 참조하십시오.


0

받아 들여진 대답은 나를 위해 일했습니다. 아래는 Selenium이 보이지 않는다고 생각하게 만드는 부모 요소를 찾는 코드입니다.

function getStyles(element){
	
	computedStyle = window.getComputedStyle(element);

	if(computedStyle.opacity === 0
	|| computedStyle.display === "none"
	|| computedStyle.visibility === "hidden"
	|| (computedStyle.height < 0 && computedStyle.height < 0)
	|| element.type === "hidden") {
		console.log("Found an element that Selenium will consider to not be visible")
		console.log(element);
		console.log("opacity: " + computedStyle.opacity);
		console.log("display: " + computedStyle.display);
		console.log("visibility: " + computedStyle.visibility);
		console.log("height: " + computedStyle.height);
		console.log("width: " + computedStyle.width);
	}

	if(element.parentElement){
		getStyles(element.parentElement);
	}
}

getStyles(document.getElementById('REPLACE WITH THE ID OF THE ELEMENT YOU THINK IS VISIBLE BUT SELENIUM CAN NOT FIND'));


0

여기에 내 모래 알갱이를 추가하려면 : 요소가 고정 div 뒤에 있으면 보이지 않는 것으로 간주되고 클릭 할 수 없습니다. 이것은 최근에 나에게 일어 났고 위에서 권장 한대로 스크립트를 실행하여 해결했습니다.

document.evaluate("<xpath locator for element to be clicked>", document, null, XPathResult.ANY_TYPE, null).iterateNext().click()", locator);

여기 로케이터는 무엇입니까?
Anjana
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.