During my test run there is bunch of js scripts that create global constants I have to access later. The codebase is currently built the way I can't avoid it. Essentially happen next things: a page opens, in one call one script is executed and in another call is another script is executed.
from selenium import webdriver
with webdriver.Firefox() as driver:
driver.get("http://127.0.0.1:8000")
driver.execute_script("const x = 1;")
driver.execute_script("console.log(x + 1);")
Everything crashes with this error.
Traceback (most recent call last):
File "test_hello_selenium.py", line 24, in <module>
driver.execute_script("console.log(x += 1);")
File "~/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 636, in execute_script
'args': converted_args})['value']
File "~/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "~/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.JavascriptException: Message: ReferenceError: x is not defined
Actually, driver doesn't matter. With chromedriver the error stays the same.
The actual question is how to achieve the correct result without merging two js scripts into one or understand why it is not possible.
1 Answer 1
Every call to execute_script invokes the specified JavaScript in the context of an anonymous function. This is by design so as not to pollute the DOM of the page being automated. The implication of that is that any variables created in a call are scoped to the duration of that call. To access the variable outside that scope, you’d need to explicitly store it in the page DOM, like this:
# Note: could also use window instead
# of document
driver.execute_script("document.x = 1;")
driver.execute_script("console.log(document.x + 1);")