npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

sefiutils

v1.0.56

Published

Utilities (and Jest tests) for Selenium Webdriver Tests and some React tools as well

Downloads

53

Readme

npm pipeline status coverage

logo 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 variable SEFI_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 waitFor
  • saveScreenshot -- saves a screenshot to a file
  • getElementById, getElementByClass, getElementByTag -- returns the (first) element with the given id, class or tag
  • getElementContainingText -- returns the (first) element containing the given text
  • getBoundingClientRect, getBoundingClientRects -- returns the bounding rectangle(s) of the given element(s)
  • getComputedStyle -- returns the computed style of the given element
  • getInheritedBackgroundColorsByJS, getInheritedColorsByJS -- returns the inherited (background) color of the given element
  • getInnerSizeOfWindow, getViewPortSize -- returns the inner size of the window or the viewport size
  • setBrowserWindowSize -- 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 rectangle
  • setViewPortSize -- sets the size of the viewport
  • getButtonsAndHRefs -- 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:

  1. Install rewire: npm install rewire
  2. 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;
  3. Instead of calling npm run build, just call node 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.