sefiutils
v1.0.56
Published
Utilities (and Jest tests) for Selenium Webdriver Tests and some React tools as well
Downloads
53
Readme
sefiutils
Utilities (and Jest tests) for Selenium Webdriver Tests and some React tools as well
[[TOC]]
Overview
This package provides some utility functions for Selenium Webdriver. It also adds some utilities for React Fiber in order to make it easier to test React components -- however it has no dependency to React itself. Additionally setup and teardown functions for Jest are provided.
If you want to test your web app, you probably want to use other frameworks. This package is intended for use in teaching, in particular for grading student's projects. Thus it provides some utilities which are usually not available in other frameworks (as they are usually not required at all).
Install
Install with npm:
npm install --save-dev sefiutils
Usage
In your jest.config.js file add the following lines:
globalSetup: "<rootDir>/node_modules/sefiutils/lib/globalSetup.js",
globalTeardown: "<rootDir>/node_modules/sefiutils/lib/globalTeardown.js"
globalSetup: "<rootDir>/../node_modules/sefiutils/lib/globalSetup.js",
globalTeardown: "<rootDir>/../node_modules/sefiutils/lib/globalTeardown.js"
would not work. In this case, create your own global files and reexport the sefituils ones, e.g. Create a file 'globalSetup.js' in your project with the following content:
module.exports = require("sefiutils/lib/globalSetup.js");
Depending on the environment variable SEFI_BROWSER
either a browser is started or a
selenium server is started. The following values are supported:
remote
: A selenium server is started. This requires Java as well! By default, selenium server 4.1.16 is used, but this can be changed via environment variableSEFI_SELENIUM_SERVER_VERSION
. The jar file is automatically downloaded to~/.cache/selenium-server
if not already present.chrome
: A Chrome browser is started. This requires chromedriver (and @types/chromediver) to be installed.firefox
: A Firefox browser is started.
In your tests, add the following lines (or similar) to setup and teardown the driver and load the page:
import { LOCAL_SETUP_TIMEOUT, localSetup} from "sefiutils/lib/localSetup"
import { localTeardown} from "sefiutils/lib/localTeardown"
const page = "http://localhost:3000/" // or any other page
let driver: WebDriver;
beforeAll(async () => {
try {
driver = await localSetup(page, 600, 700);
} catch (err) {
throw new Error(`Cannot open page ${page}`);
}
}, LOCAL_SETUP_TIMEOUT);
afterAll(async () => {
await localTeardown(driver);
});
Utility Functions
Utils for accessing information from the DOM via Selenium Webdriver injected JavaScript
Most utility functions are provided via module 'seUtils', e.g.
waitFor
-- similar to React Testing Library's waitForsaveScreenshot
-- saves a screenshot to a filegetElementById
,getElementByClass
,getElementByTag
-- returns the (first) element with the given id, class or taggetElementContainingText
-- returns the (first) element containing the given textgetBoundingClientRect
,getBoundingClientRects
-- returns the bounding rectangle(s) of the given element(s)getComputedStyle
-- returns the computed style of the given elementgetInheritedBackgroundColorsByJS
,getInheritedColorsByJS
-- returns the inherited (background) color of the given elementgetInnerSizeOfWindow
,getViewPortSize
-- returns the inner size of the window or the viewport sizesetBrowserWindowSize
-- sets the size of the browser window (this is directly supported by newer Selenium webdriver versions and only required for older versions)waitForSetRect
-- waits until the given element has the given bounding rectanglesetViewPortSize
-- sets the size of the viewportgetButtonsAndHRefs
-- returns all buttons and anchors with hrefs of the given element
Most of these functions are scripts executed in the browser via Selenium Webdriver's executeScript
function.
Utils for React Fiber
If you want to test the React components hierarchy, you can use the following functions:
import { ComponentNode, dumpComponentTree, findAllInComponentTree,
findInComponentTree, getReactComponentTree} from "sefiutils/lib/fiberUtils"
await waitFor(async () => {
cmpTree = await getReactComponentTree(driver);
const component = findInComponentTree(cmpTree, (node) => equalsIgnoreCase(node.name, "App"));
expect(component).toBeTruthy();
}, 5000, 1000);
For debugging, you can also dump the tree;
console.log("Component Tree:\n" + dumpComponentTree(cmpTree));
Note that in production build, webpack (i.e, terser) replaces all class and function names. Since the component names are simply the function names, they are replaced as well.
In order to keep the names, you must use a trick described by François Zaninotto in his blog. The trick there is a bit outdated, so this is how it works now:
- Install rewire:
npm install rewire
- Write a small script, e.g. build.js as follows:
const rewire = require('rewire'); const defaults = rewire('react-scripts/scripts/build.js'); const config = defaults.__get__('config'); // console.log(JSON.stringify(config, null, 2)); config.optimization.minimizer[0].options.minimizer.options.keep_classnames = true; config.optimization.minimizer[0].options.minimizer.options.keep_fnames = true;
- Instead of calling
npm run build
, just callnode build.js
. Of course you can also use that as your new build script.
If you get an error or the trick does not work, uncomment the log line to see the actual structure of your config.
Logging etc.
In order to see what's going on, set environment variable SEFI_VERBOSE
to true.
If you have problems starting the driver or something like that, set the environment variable SEFI_DEBUG
to true. This will output information about local start up process.
Docker Hints
If you want to run your JavaScript tests in a docker container, you can use the following Dockerfile seleniumnode20
:
# build with: docker build -t seleniumnode20 .
# User: seluser, Home: /home/seluser, Shell: /bin/bash
FROM selenium/standalone-firefox:latest
# install Node 20 and NPM
RUN sudo apt update
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
RUN sudo apt install -y nodejs
CMD ["/bin/bash"]
The default user ist "seluser", i.e. home folder is found in "/home/seluser".
Configuration
Several environment variables can be used to configure SEFIUTILS.
- SEFI_BROWSER, at the moment only remvote is supported, default remote
- SEFI_SELENIUM_SERVER_VERSION, the selenium server version, default 4.16.1
- SEFI_LOG_LEVEL, the log level, can be log, verbose or debug, default log
- SEFI_SELENIUM_REMOTE_URL, the URL, only the port is really configurable, default http://localhost:4444/wd/hub
- SEFI_SELENIUM_SERVER_START_TIMEOUT, timeout when starting the remote selenium server, default 5000
- SEFI_SELENIUM_SERVER_DOWNLOAD_URL, URL (prefix) from where the selenium server jar will be downloaded, default https://github.com/SeleniumHQ/selenium/releases/download
- SEFI_SELENIUM_CACHE_FOLDER: The folder to which the selenium server jar is downloaded (inside a folder ./cache and the selenium version). If not specified, the homefolder of the current user is used. However, in some cases (Docker, Gitlab) this is not possible.
The environment is also passed to Selenium, so specific Selenium configurations can be set as well.
Troubleshooting
If the selenium server cannot be started, you might check whether any server is listing at the port via
lsof -i :4444 -t
(and you might kill it via kill -15 $(lsof -i :4444 -t)
)
License
This program and the accompanying materials are made available under the terms of the Eclipse Public License v. 2.0 which is available at https://www.eclipse.org/legal/epl-2.0.