Created
February 13, 2022 15:39
-
-
Save ifuchs/e3ee59aec7885ec9336034ab27128f5f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ python -m pytest wordle_new.py | |
============================= test session starts ============================== | |
platform darwin -- Python 3.9.7, pytest-7.0.1, pluggy-1.0.0 | |
rootdir: /Users/ihf | |
plugins: seleniumbase-2.4.12, html-2.0.1, xdist-2.5.0, forked-1.4.0, rerunfailures-10.2, metadata-1.11.0, ordering-0.6 | |
collected 1 item | |
wordle_new.py F [100%] | |
=================================== FAILURES =================================== | |
___________________________ WordleTests.test_wordle ____________________________ | |
self = <wordle_new.WordleTests testMethod=test_wordle> | |
selector = 'game-app::shadow game-keyboard::shadow button[data-key="?"]' | |
timeout = 6, must_be_visible = True | |
def __get_shadow_element( | |
self, selector, timeout=None, must_be_visible=False | |
): | |
self.wait_for_ready_state_complete() | |
if timeout is None: | |
timeout = settings.SMALL_TIMEOUT | |
elif timeout == 0: | |
timeout = 0.1 # Use for: is_shadow_element_* (* = present/visible) | |
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: | |
timeout = self.__get_new_timeout(timeout) | |
self.__fail_if_invalid_shadow_selector_usage(selector) | |
if "::shadow " not in selector: | |
raise Exception( | |
'A Shadow DOM selector must contain at least one "::shadow "!' | |
) | |
selectors = selector.split("::shadow ") | |
element = self.get_element(selectors[0]) | |
selector_chain = selectors[0] | |
is_present = False | |
for selector_part in selectors[1:]: | |
shadow_root = None | |
if ( | |
selenium4 | |
and self.is_chromium() | |
and int(self.__get_major_browser_version()) >= 96 | |
): | |
try: | |
shadow_root = element.shadow_root | |
except Exception: | |
if self.browser == "chrome": | |
chrome_dict = self.driver.capabilities["chrome"] | |
chrome_dr_version = chrome_dict["chromedriverVersion"] | |
chromedriver_version = chrome_dr_version.split(" ")[0] | |
major_c_dr_version = chromedriver_version.split(".")[0] | |
if int(major_c_dr_version) < 96: | |
upgrade_to = "latest" | |
major_browser_version = ( | |
self.__get_major_browser_version() | |
) | |
if int(major_browser_version) >= 96: | |
upgrade_to = str(major_browser_version) | |
message = ( | |
"You need to upgrade to a newer\n" | |
"version of chromedriver to interact\n" | |
"with Shadow root elements!\n" | |
"(Current driver version is: %s)" | |
"\n(Minimum driver version is: 96.*)" | |
"\nTo upgrade, run this:" | |
'\n"seleniumbase install chromedriver %s"' | |
% (chromedriver_version, upgrade_to) | |
) | |
raise Exception(message) | |
if timeout != 0.1: # Skip wait for special 0.1 (See above) | |
time.sleep(2) | |
try: | |
shadow_root = element.shadow_root | |
except Exception: | |
raise Exception( | |
"Element {%s} has no shadow root!" % selector_chain | |
) | |
else: # This part won't work on Chrome 96 or newer. | |
# If using Chrome 96 or newer (and on an old Python version), | |
# you'll need to upgrade in order to access Shadow roots. | |
# Firefox users will likely hit: | |
# https://github.com/mozilla/geckodriver/issues/1711 | |
# When Firefox adds support, switch to element.shadow_root | |
try: | |
shadow_root = self.execute_script( | |
"return arguments[0].shadowRoot", element | |
) | |
except Exception: | |
time.sleep(2) | |
shadow_root = self.execute_script( | |
"return arguments[0].shadowRoot", element | |
) | |
if timeout == 0.1 and not shadow_root: | |
raise Exception( | |
"Element {%s} has no shadow root!" % selector_chain | |
) | |
elif not shadow_root: | |
time.sleep(2) # Wait two seconds for the shadow root to appear | |
shadow_root = self.execute_script( | |
"return arguments[0].shadowRoot", element | |
) | |
if not shadow_root: | |
raise Exception( | |
"Element {%s} has no shadow root!" % selector_chain | |
) | |
selector_chain += "::shadow " | |
selector_chain += selector_part | |
try: | |
if ( | |
selenium4 | |
and self.is_chromium() | |
and int(self.__get_major_browser_version()) >= 96 | |
): | |
if timeout == 0.1: | |
element = shadow_root.find_element( | |
By.CSS_SELECTOR, value=selector_part) | |
else: | |
found = False | |
for i in range(int(timeout) * 4): | |
try: | |
element = shadow_root.find_element( | |
By.CSS_SELECTOR, value=selector_part) | |
is_present = True | |
if must_be_visible: | |
if not element.is_displayed(): | |
raise Exception( | |
"Shadow Root element not visible!") | |
found = True | |
break | |
except Exception: | |
time.sleep(0.2) | |
continue | |
if not found: | |
element = shadow_root.find_element( | |
By.CSS_SELECTOR, value=selector_part) | |
/anaconda3/envs/py39/lib/python3.9/site-packages/seleniumbase/fixtures/base_case.py:6048: | |
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |
self = <selenium.webdriver.remote.shadowroot.ShadowRoot (session="ade4c90bff3d54ad0b5b90429c58abca", element="d46b2141-b2d9-4862-ac12-3337153354bc")> | |
using = 'css selector', value = 'button[data-key="?"]' | |
def find_element(self, using, value): | |
return self._execute(Command.FIND_ELEMENT_FROM_SHADOW_ROOT, {"using": using, "value": value})['value'] | |
/anaconda3/envs/py39/lib/python3.9/site-packages/selenium/webdriver/remote/shadowroot.py:45: | |
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |
self = <selenium.webdriver.remote.shadowroot.ShadowRoot (session="ade4c90bff3d54ad0b5b90429c58abca", element="d46b2141-b2d9-4862-ac12-3337153354bc")> | |
command = 'findElementFromShadowRoot' | |
params = {'sessionId': 'ade4c90bff3d54ad0b5b90429c58abca', 'shadowId': 'd46b2141-b2d9-4862-ac12-3337153354bc', 'using': 'css selector', 'value': 'button[data-key="?"]'} | |
def _execute(self, command, params=None): | |
"""Executes a command against the underlying HTML element. | |
Args: | |
command: The name of the command to _execute as a string. | |
params: A dictionary of named parameters to send with the command. | |
Returns: | |
The command's JSON response loaded into a dictionary object. | |
""" | |
if not params: | |
params = {} | |
params['shadowId'] = self._id | |
return self.session.execute(command, params) | |
/anaconda3/envs/py39/lib/python3.9/site-packages/selenium/webdriver/remote/shadowroot.py:64: | |
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |
self = <selenium.webdriver.chrome.webdriver.WebDriver (session="ade4c90bff3d54ad0b5b90429c58abca")> | |
driver_command = 'findElementFromShadowRoot' | |
params = {'shadowId': 'd46b2141-b2d9-4862-ac12-3337153354bc', 'using': 'css selector', 'value': 'button[data-key="?"]'} | |
def execute(self, driver_command: str, params: dict = None) -> dict: | |
""" | |
Sends a command to be executed by a command.CommandExecutor. | |
:Args: | |
- driver_command: The name of the command to execute as a string. | |
- params: A dictionary of named parameters to send with the command. | |
:Returns: | |
The command's JSON response loaded into a dictionary object. | |
""" | |
if self.session_id: | |
if not params: | |
params = {'sessionId': self.session_id} | |
elif 'sessionId' not in params: | |
params['sessionId'] = self.session_id | |
params = self._wrap_value(params) | |
response = self.command_executor.execute(driver_command, params) | |
if response: | |
self.error_handler.check_response(response) | |
/anaconda3/envs/py39/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py:424: | |
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |
self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x10a0aa280> | |
response = {'status': 404, 'value': '{"value":{"error":"no such element","message":"no such element: Unable to locate element: {\...7fff6bd96249 _pthread_start + 66\\n23 libsystem_pthread.dylib 0x00007fff6bd9240d thread_start + 13\\n"}}'} | |
def check_response(self, response: Dict[str, Any]) -> None: | |
""" | |
Checks that a JSON response from the WebDriver does not have an error. | |
:Args: | |
- response - The JSON response from the WebDriver server as a dictionary | |
object. | |
:Raises: If the response contains an error message. | |
""" | |
status = response.get('status', None) | |
if not status or status == ErrorCode.SUCCESS: | |
return | |
value = None | |
message = response.get("message", "") | |
screen: str = response.get("screen", "") | |
stacktrace = None | |
if isinstance(status, int): | |
value_json = response.get('value', None) | |
if value_json and isinstance(value_json, str): | |
import json | |
try: | |
value = json.loads(value_json) | |
if len(value.keys()) == 1: | |
value = value['value'] | |
status = value.get('error', None) | |
if not status: | |
status = value.get("status", ErrorCode.UNKNOWN_ERROR) | |
message = value.get("value") or value.get("message") | |
if not isinstance(message, str): | |
value = message | |
message = message.get('message') | |
else: | |
message = value.get('message', None) | |
except ValueError: | |
pass | |
exception_class: Type[WebDriverException] | |
if status in ErrorCode.NO_SUCH_ELEMENT: | |
exception_class = NoSuchElementException | |
elif status in ErrorCode.NO_SUCH_FRAME: | |
exception_class = NoSuchFrameException | |
elif status in ErrorCode.NO_SUCH_SHADOW_ROOT: | |
exception_class = NoSuchShadowRootException | |
elif status in ErrorCode.NO_SUCH_WINDOW: | |
exception_class = NoSuchWindowException | |
elif status in ErrorCode.STALE_ELEMENT_REFERENCE: | |
exception_class = StaleElementReferenceException | |
elif status in ErrorCode.ELEMENT_NOT_VISIBLE: | |
exception_class = ElementNotVisibleException | |
elif status in ErrorCode.INVALID_ELEMENT_STATE: | |
exception_class = InvalidElementStateException | |
elif status in ErrorCode.INVALID_SELECTOR \ | |
or status in ErrorCode.INVALID_XPATH_SELECTOR \ | |
or status in ErrorCode.INVALID_XPATH_SELECTOR_RETURN_TYPER: | |
exception_class = InvalidSelectorException | |
elif status in ErrorCode.ELEMENT_IS_NOT_SELECTABLE: | |
exception_class = ElementNotSelectableException | |
elif status in ErrorCode.ELEMENT_NOT_INTERACTABLE: | |
exception_class = ElementNotInteractableException | |
elif status in ErrorCode.INVALID_COOKIE_DOMAIN: | |
exception_class = InvalidCookieDomainException | |
elif status in ErrorCode.UNABLE_TO_SET_COOKIE: | |
exception_class = UnableToSetCookieException | |
elif status in ErrorCode.TIMEOUT: | |
exception_class = TimeoutException | |
elif status in ErrorCode.SCRIPT_TIMEOUT: | |
exception_class = TimeoutException | |
elif status in ErrorCode.UNKNOWN_ERROR: | |
exception_class = WebDriverException | |
elif status in ErrorCode.UNEXPECTED_ALERT_OPEN: | |
exception_class = UnexpectedAlertPresentException | |
elif status in ErrorCode.NO_ALERT_OPEN: | |
exception_class = NoAlertPresentException | |
elif status in ErrorCode.IME_NOT_AVAILABLE: | |
exception_class = ImeNotAvailableException | |
elif status in ErrorCode.IME_ENGINE_ACTIVATION_FAILED: | |
exception_class = ImeActivationFailedException | |
elif status in ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS: | |
exception_class = MoveTargetOutOfBoundsException | |
elif status in ErrorCode.JAVASCRIPT_ERROR: | |
exception_class = JavascriptException | |
elif status in ErrorCode.SESSION_NOT_CREATED: | |
exception_class = SessionNotCreatedException | |
elif status in ErrorCode.INVALID_ARGUMENT: | |
exception_class = InvalidArgumentException | |
elif status in ErrorCode.NO_SUCH_COOKIE: | |
exception_class = NoSuchCookieException | |
elif status in ErrorCode.UNABLE_TO_CAPTURE_SCREEN: | |
exception_class = ScreenshotException | |
elif status in ErrorCode.ELEMENT_CLICK_INTERCEPTED: | |
exception_class = ElementClickInterceptedException | |
elif status in ErrorCode.INSECURE_CERTIFICATE: | |
exception_class = InsecureCertificateException | |
elif status in ErrorCode.INVALID_COORDINATES: | |
exception_class = InvalidCoordinatesException | |
elif status in ErrorCode.INVALID_SESSION_ID: | |
exception_class = InvalidSessionIdException | |
elif status in ErrorCode.UNKNOWN_METHOD: | |
exception_class = UnknownMethodException | |
else: | |
exception_class = WebDriverException | |
if not value: | |
value = response['value'] | |
if isinstance(value, str): | |
raise exception_class(value) | |
if message == "" and 'message' in value: | |
message = value['message'] | |
screen = None # type: ignore[assignment] | |
if 'screen' in value: | |
screen = value['screen'] | |
stacktrace = None | |
st_value = value.get('stackTrace') or value.get('stacktrace') | |
if st_value: | |
if isinstance(st_value, str): | |
stacktrace = st_value.split('\n') | |
else: | |
stacktrace = [] | |
try: | |
for frame in st_value: | |
line = self._value_or_default(frame, 'lineNumber', '') | |
file = self._value_or_default(frame, 'fileName', '<anonymous>') | |
if line: | |
file = "%s:%s" % (file, line) | |
meth = self._value_or_default(frame, 'methodName', '<anonymous>') | |
if 'className' in frame: | |
meth = "%s.%s" % (frame['className'], meth) | |
msg = " at %s (%s)" | |
msg = msg % (meth, file) | |
stacktrace.append(msg) | |
except TypeError: | |
pass | |
if exception_class == UnexpectedAlertPresentException: | |
alert_text = None | |
if 'data' in value: | |
alert_text = value['data'].get('text') | |
elif 'alert' in value: | |
alert_text = value['alert'].get('text') | |
raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here | |
raise exception_class(message, screen, stacktrace) | |
E selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"button[data-key="?"]"} | |
E (Session info: chrome=98.0.4758.80) | |
E Stacktrace: | |
E 0 chromedriver 0x00000001080d83c9 chromedriver + 5018569 | |
E 1 chromedriver 0x0000000108063333 chromedriver + 4539187 | |
E 2 chromedriver 0x0000000107c38a88 chromedriver + 170632 | |
E 3 chromedriver 0x0000000107c6d332 chromedriver + 385842 | |
E 4 chromedriver 0x0000000107c6d521 chromedriver + 386337 | |
E 5 chromedriver 0x0000000107c61ed7 chromedriver + 339671 | |
E 6 chromedriver 0x0000000107c8a80d chromedriver + 505869 | |
E 7 chromedriver 0x0000000107c61de5 chromedriver + 339429 | |
E 8 chromedriver 0x0000000107c8a8ee chromedriver + 506094 | |
E 9 chromedriver 0x0000000107c9d604 chromedriver + 583172 | |
E 10 chromedriver 0x0000000107c8a6d3 chromedriver + 505555 | |
E 11 chromedriver 0x0000000107c6095e chromedriver + 334174 | |
E 12 chromedriver 0x0000000107c61935 chromedriver + 338229 | |
E 13 chromedriver 0x00000001080941ee chromedriver + 4739566 | |
E 14 chromedriver 0x00000001080adf51 chromedriver + 4845393 | |
E 15 chromedriver 0x00000001080b3928 chromedriver + 4868392 | |
E 16 chromedriver 0x00000001080aea7a chromedriver + 4848250 | |
E 17 chromedriver 0x0000000108088c31 chromedriver + 4693041 | |
E 18 chromedriver 0x00000001080c9978 chromedriver + 4958584 | |
E 19 chromedriver 0x00000001080c9b01 chromedriver + 4958977 | |
E 20 chromedriver 0x00000001080df795 chromedriver + 5048213 | |
E 21 libsystem_pthread.dylib 0x00007fff6bd932eb _pthread_body + 126 | |
E 22 libsystem_pthread.dylib 0x00007fff6bd96249 _pthread_start + 66 | |
E 23 libsystem_pthread.dylib 0x00007fff6bd9240d thread_start + 13 | |
/anaconda3/envs/py39/lib/python3.9/site-packages/selenium/webdriver/remote/errorhandler.py:247: NoSuchElementException | |
During handling of the above exception, another exception occurred: | |
self = <wordle_new.WordleTests testMethod=test_wordle> | |
def test_wordle(self): | |
self.skip_if_incorrect_env() | |
self.open("https://www.nytimes.com/games/wordle/index.html") | |
self.click("game-app::shadow game-modal::shadow game-icon") | |
self.initalize_word_list() | |
keyboard_base = "game-app::shadow game-keyboard::shadow " | |
word = random.choice(self.word_list) | |
total_attempts = 0 | |
success = False | |
for attempt in range(6): | |
total_attempts += 1 | |
word = random.choice(self.word_list) | |
letters = [] | |
for letter in word: | |
letters.append(letter) | |
button = 'button[data-key="%s"]' % letter | |
self.click(keyboard_base + button) | |
button = 'button[data-key="?"]' | |
self.click(keyboard_base + button) | |
wordle_new.py:78: | |
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |
/anaconda3/envs/py39/lib/python3.9/site-packages/seleniumbase/fixtures/base_case.py:230: in click | |
self.__shadow_click(selector, timeout) | |
/anaconda3/envs/py39/lib/python3.9/site-packages/seleniumbase/fixtures/base_case.py:6089: in __shadow_click | |
element = self.__get_shadow_element( | |
/anaconda3/envs/py39/lib/python3.9/site-packages/seleniumbase/fixtures/base_case.py:6071: in __get_shadow_element | |
page_actions.timeout_exception(the_exception, msg) | |
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |
exception = <class 'selenium.common.exceptions.ElementNotVisibleException'> | |
message = '\n Shadow DOM Element {game-app::shadow game-keyboard::shadow button[data-key="?"]} was not visible after 6 seconds!' | |
def timeout_exception(exception, message): | |
exception, message = s_utils.format_exc(exception, message) | |
raise exception(message) | |
E selenium.common.exceptions.ElementNotVisibleException: Message: | |
E Shadow DOM Element {game-app::shadow game-keyboard::shadow button[data-key="?"]} was not visible after 6 seconds! | |
/anaconda3/envs/py39/lib/python3.9/site-packages/seleniumbase/fixtures/page_actions.py:163: ElementNotVisibleException | |
----------------------- LogPath: /Users/ihf/latest_logs/ ----------------------- | |
=========================== short test summary info ============================ | |
FAILED wordle_new.py::WordleTests::test_wordle - selenium.common.exceptions.E... | |
============================== 1 failed in 11.70s ============================== |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment