Python

[Selenium] Selenium Expected Condition 정리

메바동 2021. 10. 30. 00:40
728x90

이전 Selenium의 명시적 대기를 정리하면서 expected condition을 그냥 번역기로 정리해서 대충 살펴보았다.

하지만 번역기로 번역하였기에 이해가 가지 않는 부분들이 많았고 직접 하나씩 확인해보며 어떤 상태인지 알아보기로 하였다.

 

머리가 나쁘면 몸이 고생한다.

 

 

 

1. title_is(title)

우선 title_is는 파라미터로 str 타입의 text를 받는다.

 

 

title_is는 head에 선언된 title의 속성을 비교하는데 쉽게 말해 탭에 표시되는 제목을 확인하는 것이다.

 

driver = open_driver()
driver.get("https://naver.com")
try:
    wait = WebDriverWait(driver, 5).until(
        EC.title_is('NAVER')
    )

    log.debug(wait)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

위 코드를 실행하면 wait에는 True가 저장된다.

 

 

title_is는 대소문자를 구분하기 때문에 파라미터로 'naver'을 넘겼을 경우에는

 

 

에러가 발생하여 except 문이 실행되게 된다.

 

 

 

2. title_contains(title)

title_contains는 title_is와 같이 파라미터로 str 타입의 text를 받는다.

 

driver = open_driver()
driver.get("https://naver.com")
try:
    wait = WebDriverWait(driver, 5).until(
        EC.title_contains('VER')
    )

    log.debug(wait)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

title_contains는 title에 포함되는지 확인하는 것이기 때문에 위와 같이 'VER'을 넘겼을 경우에 wait에 True가 저장되게 된다.

 

 

title_is와 동일하게 대소문자를 구분한다.

 

 

 

3. presence_of_element_located(locator)

presence_of_element_located는 파라미터로 locator를 받는다.

페이지의 DOM에 요소가 있는지 확인하기 위한 메서드로 요소가 표시되지 않아도 해당 요소가 존재하면 element를 반환한다.

 

 

Spring 공식 페이지에 접속해보면 다음과 같이 Guides 항목은 Learn에 mouse hover가 발생하기 전까지 보이지 않는 항목이다.

 

driver = open_driver()
driver.get("https://spring.io/")
try:
    element = WebDriverWait(driver, 5).until(
        EC.presence_of_element_located((By.XPATH, '//div[@id="learn-items"]//a[@href="/guides"]'))
    )

    log.debug(element)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

위 코드를 실행하면 element에는 해당 요소가 저장된다.

 

 

만약 요소가 지정된 시간 (위 코드에서는 5초) 동안 발견되지 않으면 에러가 발생하여 except 문이 실행되게 된다.

href 속성의 값이 '/guides'가 아닌 '/guides_sample'인 요소를 지정하면

 

 

다음과 같이 에러가 발생한다.

 

 

 

4. visibility_of_element_located(locator)

visibility_of_element_located는 해당 요소가 페이지에 존재하며 화면에 표시되어 있는지 확인한다.

presence_of_element_located에서 확인했던 Guide 항목은 Learn에 mouse hover를 하지 않는 이상 표시되지 않는다. 따라서

 

driver = open_driver()
driver.get("https://spring.io/")
try:
    element = WebDriverWait(driver, 5).until(
        EC.visibility_of_element_located((By.XPATH, '//div[@id="learn-items"]//a[@href="/guides"]'))
    )

    log.debug(element)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

위 코드를 실행하면

 

 

다음과 같이 에러가 발생하게 된다.

하지만

 

driver = open_driver()
driver.get("https://spring.io/")
try:
    hover_element = driver.find_element(By.XPATH, '//div[@id="learn-hov"]/span')
    ActionChains(driver).move_to_element(hover_element).perform()

    element = WebDriverWait(driver, 5).until(
        EC.visibility_of_element_located((By.XPATH, '//div[@id="learn-items"]//a[@href="/guides"]'))
    )

    log.debug(element)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

다음과 같이 Learn에 hover 액션을 주고 visibility_of_element_located를 사용할 시에는

 

 

위와 같이 element에 해당 요소가 저장되는 것을 확인할 수 있다.

 

 

 

5. visibility_of(element)

visibility_of는 visibility_of_element_located와 역할이 비슷하지만 파라미터로 element를 전달받는다.

 

driver = open_driver()
driver.get("https://spring.io/")
try:
    element = WebDriverWait(driver, 5).until(
        EC.visibility_of(driver.find_element(By.XPATH, '//div[@id="learn-items"]//a[@href="/guides"]'))
    )

    log.debug(element)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

따라서 위 코드는 visibilty_of_element_located와 동일하게 에러가 발생하게 된다.

 

 

때문에 visibilty_of_element_located와 같이 hover 액션을 주고 실행하게 되면

 

 

해당 요소를 반환하게 된다.

 

 

 

6. presence_of_all_elements_located(locator)

presence_of_all_elements_located는 presence_of_element_located와 비슷하지만 페이지 상에 존재하는 모든 요소를 반환한다.

Spring 공식 페이지의 메인에는

 

 

위와 같이 href 속성의 값으로 '/guides'를 갖는 요소가 3개 존재한다.

이를 presence_of_element_located로 찾을 시

 

 

요소 하나만을 반환하지만

 

driver = open_driver()
driver.get("https://spring.io/")
try:
    element = WebDriverWait(driver, 5).until(
        EC.presence_of_all_elements_located((By.XPATH, '//*[@href="/guides"]'))
    )

    log.debug(element)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

 presence_of_all_elements_located로 찾게 될 시

 

 

존재하는 요소 3개를 리스트로 반환하는 것을 확인할 수 있다.

 

 

 

7. text_to_be_present_in_element(locator, text)

text_to_be_present_in_element는 로케이터와 텍스트를 파라미터로 받으며 해당 요소에 텍스트가 존재하는지 확인한다.

 

 

위에서 계속해서 찾아본 href 속성의 값으로 '/guides'를 같은 a 요소의 경우 innerText로 'Guides'라는 텍스트를 갖고 있다.

 

driver = open_driver()
driver.get("https://spring.io/")
try:
    hover_element = driver.find_element(By.XPATH, '//div[@id="learn-hov"]/span')
    ActionChains(driver).move_to_element(hover_element).perform()

    wait = WebDriverWait(driver, 5).until(
        EC.text_to_be_present_in_element((By.XPATH, '//div[@id="learn-items"]//a[@href="/guides"]'), 'Guides')
    )

    log.debug(wait)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

따라서 위의 코드를 실행시켜 보면

 

 

wait는 True를 저장하고 있다.

주의할 점은 locator로 지정한 요소가 화면에 보이는 상태로 있어야 한다.

 

 

 

8. text_to_be_present_in_element_value(locator, text)

text_to_be_present_in_element_value는 이름 그대로 요소의 value 값으로 text를 갖는지 확인한다.

 

 

Spring 공식 페이지의 메인 화면에서 하단 부분에 있는 체크박스는 긴 문자열을 value로 갖고 있다.

해당 요소를 locator로 지정하고 해당 text를 넘겨주면

 

driver = open_driver()
driver.get("https://spring.io/")
try:
    hover_element = driver.find_element(By.XPATH, '//div[@id="learn-hov"]/span')
    ActionChains(driver).move_to_element(hover_element).perform()

    wait = WebDriverWait(driver, 5).until(
        EC.text_to_be_present_in_element_value((By.XPATH, '//input[@name="gdprconsent"]'),
                                                'Yes, I would like to be contacted by The Spring Team and VMware '
                                                'for newsletters, promotions and events')
    )

    log.debug(wait)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

 

True가 반환되는 것을 확인할 수 있다.

 

 

 

9. frame_to_be_available_and_switch_to_it(locator)

frame_to_be_available_and_switch_to_it은 아직 잘 이해를 못하겠다. iframe이 존재하는 페이지에서 해당 프레임으로 넘어갈 수 있는지 여부를 확인하고 넘어갈 수 있으면 해당 프레임으로 넘겨주는 역할을 하는 것 같다.

 

 

 

10. invisibility_of_element_located(locator)

invisibility_of_element_located는 위에서 확인했던 것들과는 다르게 페이지에 보이지 않아야 에러가 발생하지 않는다.

따라서 위에서 계속해서 확인했던 guides 요소를 보이지 않는 상태에서 invisibility_of_element_located로 확인하면

 

driver = open_driver()
driver.get("https://spring.io/")
try:
    wait = WebDriverWait(driver, 5).until(
        EC.invisibility_of_element_located((By.XPATH, '//div[@id="learn-items"]//a[@href="/guides"]'))
    )

    log.debug(wait)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

 

해당 요소를 반환한다.

하지만 hover 액션을 발생시켜 확인해 보면

 

 

에러가 발생하는 것을 확인할 수 있다.

 

 

 

11. element_to_be_clickable(locator)

element_to_be_clickable은 해당 요소가 클릭할 수 있는 상태인지 확인한다.

위에서 확인했던 guides 요소는 보이는 상태에서는 클릭할 수 있지만 보이지 않는 상태에서는 클릭할 수 없는 상태이다.

 

따라서

 

driver = open_driver()
driver.get("https://spring.io/")
try:
    hover_element = driver.find_element(By.XPATH, '//div[@id="learn-hov"]/span')
    ActionChains(driver).move_to_element(hover_element).perform()

    element = WebDriverWait(driver, 5).until(
        EC.element_to_be_clickable((By.XPATH, '//div[@id="learn-items"]//a[@href="/guides"]'))
    )

    log.debug(element)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

위 코드를 실행하면

 

 

해당 요소를 반환하지만, hover 액션을 발생시키는 부분을 주석 처리하고 실행하면

 

 

클릭할 수 없는 상태이므로 에러가 발생하게 된다.

 

 

 

12. staleness_of(element)

staleness_of는 요소가 DOM에 연결되지 않을 때까지 대기한다.

DOM에 연결되지 않는다는 의미는 해당 요소가 사라진 상태를 의미한다.

 

driver = open_driver()
driver.get("http://127.0.0.1:5500")
try:
    wait = WebDriverWait(driver, 10).until(
        EC.staleness_of(driver.find_element(By.XPATH, '//div[@id="disappear-ele"]/p'))
    )

    log.debug(wait)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

5500번 포트에 5초 뒤에 요소를 remove 시키는 스크립트가 실행되는 테스트 페이지를 띄우고 위 코드를 실행시켜보면

 

 

10초 안에 해당 요소가 사라지는 것을 기다리는 것이기 때문에 True가 반환된다.

대기 시간을 3초로 줄여보면

 

 

대기 중인 3초 동안 해당 요소가 사라지지 않기 때문에 에러가 발생한다.

 

 

 

13. element_to_be_selected(element)

element_to_be_selected는 선택할 수 있는 요소(라디오 버튼, 체크박스 등)가 선택되어 있는지 확인한다.

 

네이버 회원가입 페이지에 보면

 

 

위와 같이 체크박스들이 있다.

 

driver = open_driver()
driver.get("https://nid.naver.com/user2/V2Join?m=agree&lang=ko_KR&cpno=#agreeBottom")

try:
    chklabel_ele = driver.find_element(By.XPATH, '//*[@id="termsService"]/..')
    chklabel_ele.click()

    wait = WebDriverWait(driver, 5).until(
        EC.element_to_be_selected(driver.find_element(By.XPATH, '//*[@id="termsService"]'))
    )

    log.debug(wait)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

위 코드는 네이버 회원가입 페이지에서 "네이버 이용약관 동의"가 체크되어 있는지 확인한다.

 

 

확인 전 체크박스를 선택하였기 때문에 결과는 True가 반환이 된다.

만약 선택하는 부분을 주석 처리하고 실행할 시

 

 

위와 같이 에러가 발생하게 된다.

 

 

 

14. element_located_to_be_selected(locator)

element_located_to_be_selected는 element_to_be_selected와 같이 선택할 수 있는 요소가 선택되어 있는지 확인한다.

차이점은 element_located_to_be_selected는 파라미터로 locator를 받고 element_to_be_selected는 element를 받는다.

 

driver = open_driver()
driver.get("https://nid.naver.com/user2/V2Join?m=agree&lang=ko_KR&cpno=#agreeBottom")

try:
    chklabel_ele = driver.find_element(By.XPATH, '//*[@id="termsService"]/..')
    chklabel_ele.click()

    wait = WebDriverWait(driver, 5).until(
        EC.element_located_to_be_selected((By.XPATH, '//*[@id="termsService"]'))
    )

    log.debug(wait)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

똑같이 네이버 회원가입 페이지에서 테스트해보면

 

 

동일하게 True가 반환된다.

 

 

 

15. element_selection_state_to_be(element, is_selected)

element_selection_state_to_be는 선택할 수 있는 요소가 두 번째로 전달된 is_selected(boolean값)에 만족하는지 확인한다.

 

driver = open_driver()
driver.get("https://nid.naver.com/user2/V2Join?m=agree&lang=ko_KR&cpno=#agreeBottom")

try:
    wait = WebDriverWait(driver, 5).until(
        EC.element_selection_state_to_be(driver.find_element(By.XPATH, '//*[@id="termsService"]'), False)
    )

    log.debug(wait)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

네이버 회원가입 페이지의 체크박스는 기본적으로 false가 되어있다.

element_selection_state_to_be의 두 번째 인수로 False를 넘기면

 

 

결과값으로 True가 반환된다.

하지만 위 코드에 체크박스를 선택하는 코드를 넣어주면

 

 

위와 같이 에러가 발생하게 된다.

 

 

 

16. element_located_selection_state_to_be(locator, is_selected)

element_located_selection_state_to_be는 element_selection_state_to_be와 동일하지만 첫 번째 파라미터로 element가 아닌 locator를 받는다.

 

driver = open_driver()
driver.get("https://nid.naver.com/user2/V2Join?m=agree&lang=ko_KR&cpno=#agreeBottom")

try:
    wait = WebDriverWait(driver, 5).until(
        EC.element_located_selection_state_to_be((By.XPATH, '//*[@id="termsService"]'), False)
    )

    log.debug(wait)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

따라서 위 코드는 동일하게

 

 

결과값으로 True가 반환된다.

 

 

 

17. alert_is_present

alert_is_present는 alert 창이 발생하는지 확인한다.

 

driver = open_driver()
driver.get("http://127.0.0.1:5500")

try:
    wait = WebDriverWait(driver, 5).until(
        EC.alert_is_present()
    )

    log.debug(wait)
except Exception as e:
    log.error('Selenium Test Error.')
finally:
    driver.quit()

 

5500번 포트에 alert창이 나타나는 테스트 페이지를 띄우고 위 코드를 실행시켜보면

 

 

위와 같이 alert object가 반환되게 된다.

만약 주어진 대기 시간 내에 alert창이 나타나지 않으면

 

 

에러가 발생한다.

728x90