Algorithms in the wild: Cartesian product & generating cases for end-to-end testing

Reading Time: < 1 minute

Recently I was writing Cypress tests for media query functionality that we have in the Webflow. One of the features that I wanted to cover was disabling or enabling animations on different media queries.

Currently, there are four possible media queries in Webflow: Desktop, Tablet, Phone Landscape, and Phone Portrait.

Possible media queries choices

What I wanted was to cover all 16 possible combinations of these options being enabled or disabled. For every media query, options can be presented by boolean values, so all possible options for one media query can be represented by the array [true, false].

Brute-force solution to iterate through all possible option may be creating four cycles inside which perform needed actions:


arr1.forEach(option1 => {
arr2.forEach(option2 => {
arr3.forEach(option3 => {
arr4.forEach(option4 => {
// use option1, option2, option3, option4 here
});
});
});
});

view raw

options.js

hosted with ❤ by GitHub

Calculate all possible combinations of the options for all possible media queries is calculating cartesian product so we can use next one formula:


const f = (a, b) => [].concat(…a.map(d => b.map(e => [].concat(d, e))));
const cartesian = (a, b, …c) => (b ? cartesian(f(a, b), …c) : a);

Source of the solution: https://stackoverflow.com/questions/12303989/cartesian-product-of-multiple-arrays-in-javascript

So to iterate through all possible options combinations, we need to do the following:


cartesian([arr1, arr2, arr3, arr4]).forEach(
(option1, option2, option3, option4) => {
// use option1, option2, option3, option4 here
});

view raw

options.js

hosted with ❤ by GitHub

Using the cartesian product not only allowed making code more elegant but also easier to scale, if, for example, we would need to add more media queries to account for.

If you have found a spelling error, please, notify us by selecting that text and pressing Ctrl+Enter.

Olena Sovyn
Staff Software Engineer (London, UK). I ❤ React, Redux, lodash, React Storybook, and functional programming overall. Always open to learning something new

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Spelling error report

The following text will be sent to our editors: