Skip to content

JS handling

aqualityAutomation edited this page Mar 17, 2023 · 1 revision

Selenium 4 introduces several ways to work with JavaScript on the client side (in the browser). Among them:

Client-side event listeners; Execution of JS code in the browser. In Aquality Selenium, this functionality is mainly implemented in the JavaScriptHandling class, as well as in several auxiliary classes. The work of these classes is demonstrated in the test classes DomMonitoringTest, InitializationScriptsTests, JavaScriptEventTests and JavaScriptSnippetsTests.

ConsoleEvent listener

The addJavaScriptConsoleApiListener(Consumer listener) method sets the browser console JS call listener for the current Browser instance. The listener uses an instance of the ConsoleEvent class for its work, which contains information about the script being executed. A single Browser can have multiple similar listeners at the same time. An example of using this method is given below. image In this example, a consoleListener is added that adds all messages that occur in the browser console to to the apiCalledMessages List . The stopEventMonitoring() method deletes all added JS listeners.

JavascriptException listener

The addJavaScriptExceptionThrownListener(Consumer listener) method sets up the listener for JS exceptions thrown in the browser. The listener uses an instance of the JavascriptException class for its work, containing information about a specific JS exception. A single Browser can have multiple similar listeners at the same time. An example of using this method is given below. image In this example, an exceptionListener is set that adds all JS browser exception messages to the apiCalledMessages List. The stopEventMonitoring() method removes all added JS listeners.

DomMutationEvent listener

The addDomMutatedListener(Consumer listener) method sets a listener for events that occur when element attributes change. The listener uses an instance of the DomMutationEvent class for its work, containing information about changing a particular element. A fragment of this class with fields and a constructor can be seen below. image A single Browser can have multiple similar listeners at the same time. An example of using this method is given below. image In the testSubscribeToDomMutationEventAndDisableMonitoring test, all attribute value changes are written to the attributeValueChanges list using the addDomMutatedListener(...) method. Next, a new attribute (cheese="Gouda") is added to one of the form elements and it is checked that this change was written to attributeValueChanges. It also checks the contents of the DomMutationEvent instance. Next, the state of the JavaScriptHandling instance is reset using the reset() method and it is checked that the listener is no longer running and that attribute changes are no longer written to the attributeValueChanges list.

Pinned scripts

Selenium 4 has extended the functionality of the JavascriptExecutor interface with new methods that allow to work with pinned scripts - scripts added directly to the current web driver session. That is, you can load the script once and then call it by identifier, instead of loading this code every time. In Aquality Selenium, pinned scripts are handled using two classes:

JavaScriptHandling - it implements common methods for working with scripts: ScriptKey pinScript(String script) - adds a script to the current session of the web driver and returns a ScriptKey object - the identifier of this script void unpinScript(ScriptKey pinnedScript) - removes script by key pinnedScript; void clearPinnedScripts() - removes all pinned scripts; Set getPinnedScripts() - returns the keys of all pinned scripts;

JsActions - an instance of this class contains in its fields information about the IElement element, against which the added script will be executed. Methods of this class are based on JS code execution. The peculiarity of these methods is that the first argument to the scripts is the IElement itself. Here are some of the JsActions class methods: String getXPath() - returns the xPath of an element by executing the code from getElementXPath.js; String getElementText() - returns the text of an element by executing the code from getElementText.js; void setValue(final String value) - sets a value to an element (the value attribute) by executing the code from setValue.js; Object executeScript(ScriptKey pinnedScript, Object... args) - executes the script by the given pinnedScript key with args arguments. Below are two tests that demonstrate how pinned scripts work. image In the testPinScriptAndUnpinIt test, a script (getElementXPath.js) is added, which returns the xPath of the passed element. The xPath obtained in this way is compared with the xPath obtained by the getXPath() method. Next, the previously loaded script is deleted using the unpinScript(ScriptKey pinnedScript) method and it is checked that the script is not present in this session. Finally, the state of the JavascriptHandling instance is reset using the reset() method. image In the testPinScriptWithoutReturnedValueAndUnpinAll test, a script (setValue.js) is added that sets the value of the form element (the value attribute) authenticationForm, and then the correctness of this script is checked. The rest of the steps are the same as the steps in the testPinScriptAndUnpinIt test.

Initialization scripts

Selenium 4 also added the ability to load scripts that are executed automatically on every page load. The main methods of the JavaScriptHandling class that implement this functionality:

InitializationScript addInitializationScript(String scriptName, String script) - adds a script, which will be executed on every page load, to the current web driver session. The first parameter scriptName is an alias of this script, this is the name that will be displayed in the logs. The method returns an instance of class InitializationScript, which is an identifier of the added script and contains all information about it (scriptId, scriptName, script); void removeInitializationScript(InitializationScript script) - removes the specified script from the pool of scripts that are executed on every page load; void clearInitializationScripts() - removes all IntializationScripts; List getInitializationScripts() - returns the list of scripts executed at each page load; One use case of initialisation scripts is demonstrated in the testAddInitializationScriptGetItThenRemoveOrClear test. image In this test, using the addInitializationScript(String scriptName, String script) method, a script is added that calls the Confirm Alert every time the page is loaded. The test verifies that the contents of the InitializationScript instance match the added script, as well as its functionality. The test then tests various methods for removing the initialization script (using removeInitializationScript(InitializationScript script), clearInitializationScripts(), and clearAll()).