Skip to content

Commit

Permalink
tests(QUnit & Testcafe): modify CI configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
wdevfx committed Mar 5, 2025
1 parent 538551a commit 9e9e975
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 72 deletions.
3 changes: 2 additions & 1 deletion .github/actions/run-qunit-tests/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ runs:

- name: Setup Chrome
if: ${{ inputs.browser == 'chrome' }}
uses: ./.github/actions/setup-chrome
uses: ./.github/actions/setup-chrome-headless-shell
with:
chrome-version: '133.0.6943.53'

Expand Down Expand Up @@ -139,6 +139,7 @@ runs:
GITHUBACTION: "true"
TARGET: "test"
DISPLAY: ":99"
CHROME_CMD: ${{ env.CHROME_SHELL }}
run: |
chmod +x ./docker-ci.sh
./docker-ci.sh
Expand Down
34 changes: 34 additions & 0 deletions .github/actions/setup-chrome-headless-shell/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Chrome headless shell installer
description: Install chrome-headless-shell

# Chrome headless shell
# https://developer.chrome.com/blog/chrome-headless-shell

inputs:
chrome-version:
description: Chrome headless shell version to install
default: "latest"

runs:
using: composite
steps:
- name: Setup chrome-headless-shell
shell: bash
env:
CHROME_VERSION: ${{ inputs.chrome-version }}
run: |
if [ -n "$CHROME_VERSION" ]; then
sudo apt-get update
sudo apt-get -y install libu2f-udev
sudo apt-get -y install dbus
echo "version to install: $CHROME_VERSION"
CHROME_BIN=`npx @puppeteer/browsers install chrome-headless-shell@$CHROME_VERSION | awk '{print $2}'`
chmod +x $CHROME_BIN
echo "chrome-headless-shell installed in: $CHROME_BIN"
$CHROME_BIN --version
echo "CHROME_SHELL=$CHROME_BIN" >> $GITHUB_ENV
else
echo "chrome-headless-shell not installed!"
fi
49 changes: 24 additions & 25 deletions .github/workflows/qunit_tests-additional-renovation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,24 +111,28 @@ jobs:
useJQuery: 'false'
useCsp: 'true'

qunit-tests-performance:
needs: build
runs-on: devextreme-shr2
name: Performance
timeout-minutes: 25
steps:
- name: Get sources
uses: actions/checkout@v4

- name: Run QUnit tests
uses: ./.github/actions/run-qunit-tests
with:
name: 'Performance'
browser: 'chrome'
isPerformance: 'true'
useJQuery: 'true'
headless: 'false'
useCsp: 'false'
# TODO Chrome133: skipped during chrome update
# We should run performance tests with non headless chrome
# It fails in headless mode

# qunit-tests-performance:
# needs: build
# runs-on: devextreme-shr2
# name: Performance
# timeout-minutes: 25
# steps:
# - name: Get sources
# uses: actions/checkout@v4
#
# - name: Run QUnit tests
# uses: ./.github/actions/run-qunit-tests
# with:
# name: 'Performance'
# browser: 'chrome'
# isPerformance: 'true'
# useJQuery: 'true'
# headless: 'true'
# useCsp: 'false'

qunit-tests-mobile-and-shadow-dom:
needs: build
Expand Down Expand Up @@ -157,7 +161,6 @@ jobs:
]
kind: [ 'shadow-dom', 'ios10', 'android6' ]
include:
- headless: false
- kind: 'shadow-dom'
userAgent: ''
useShadowDom: true
Expand All @@ -166,10 +169,6 @@ jobs:
- kind: 'android6'
userAgent: 'android6'
useJQuery: true
- constel: 'ui'
headless: true
- constel: 'viz'
headless: true

steps:
- name: Get sources
Expand All @@ -184,7 +183,7 @@ jobs:
useJQuery: ${{ matrix.useJquery || 'false' }}
userAgent: ${{ matrix.userAgent }}
useShadowDom: ${{ matrix.useShadowDom }}
headless: ${{ matrix.headless }}
headless: 'true'
useCsp: 'true'

qunit-tests-firefox:
Expand Down Expand Up @@ -279,7 +278,7 @@ jobs:
needs: [
build,
qunit-tests-timezones,
qunit-tests-performance,
# qunit-tests-performance,
qunit-tests-mobile-and-shadow-dom,
qunit-tests-firefox,
qunit-tests-no-csp
Expand Down
55 changes: 31 additions & 24 deletions .github/workflows/testcafe_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,27 +79,33 @@ jobs:
fail-fast: false
matrix:
ARGS: [
{ componentFolder: "accessibility", name: "accessibility (1/7)", indices: "1/7" },
{ componentFolder: "accessibility", name: "accessibility (2/7)", indices: "2/7" },
{ componentFolder: "accessibility", name: "accessibility (3/7)", indices: "3/7" },
{ componentFolder: "accessibility", name: "accessibility (4/7)", indices: "4/7" },
{ componentFolder: "accessibility", name: "accessibility (5/7)", indices: "5/7" },
{ componentFolder: "accessibility", name: "accessibility (6/7)", indices: "6/7" },
{ componentFolder: "accessibility", name: "accessibility (7/7)", indices: "7/7" },
{ componentFolder: "accessibility", name: "accessibility - material (1/7)", theme: "material.blue.light", indices: "1/7" },
{ componentFolder: "accessibility", name: "accessibility - material (2/7)", theme: "material.blue.light", indices: "2/7" },
{ componentFolder: "accessibility", name: "accessibility - material (3/7)", theme: "material.blue.light", indices: "3/7" },
{ componentFolder: "accessibility", name: "accessibility - material (4/7)", theme: "material.blue.light", indices: "4/7" },
{ componentFolder: "accessibility", name: "accessibility - material (5/7)", theme: "material.blue.light", indices: "5/7" },
{ componentFolder: "accessibility", name: "accessibility - material (6/7)", theme: "material.blue.light", indices: "6/7" },
{ componentFolder: "accessibility", name: "accessibility - material (7/7)", theme: "material.blue.light", indices: "7/7" },
{ componentFolder: "accessibility", name: "accessibility - fluent (1/7)", theme: "fluent.blue.light", indices: "1/7" },
{ componentFolder: "accessibility", name: "accessibility - fluent (2/7)", theme: "fluent.blue.light", indices: "2/7" },
{ componentFolder: "accessibility", name: "accessibility - fluent (3/7)", theme: "fluent.blue.light", indices: "3/7" },
{ componentFolder: "accessibility", name: "accessibility - fluent (4/7)", theme: "fluent.blue.light", indices: "4/7" },
{ componentFolder: "accessibility", name: "accessibility - fluent (5/7)", theme: "fluent.blue.light", indices: "5/7" },
{ componentFolder: "accessibility", name: "accessibility - fluent (6/7)", theme: "fluent.blue.light", indices: "6/7" },
{ componentFolder: "accessibility", name: "accessibility - fluent (7/7)", theme: "fluent.blue.light", indices: "7/7" },
{ componentFolder: "accessibility/common", name: "accessibility (1/7)", indices: "1/7" },
{ componentFolder: "accessibility/common", name: "accessibility (2/7)", indices: "2/7" },
{ componentFolder: "accessibility/common", name: "accessibility (3/7)", indices: "3/7" },
{ componentFolder: "accessibility/common", name: "accessibility (4/7)", indices: "4/7" },
{ componentFolder: "accessibility/common", name: "accessibility (5/7)", indices: "5/7" },
{ componentFolder: "accessibility/common", name: "accessibility (6/7)", indices: "6/7" },
{ componentFolder: "accessibility/common", name: "accessibility (7/7)", indices: "7/7" },
{ componentFolder: "accessibility/common", name: "accessibility - material (1/7)", theme: "material.blue.light", indices: "1/7" },
{ componentFolder: "accessibility/common", name: "accessibility - material (2/7)", theme: "material.blue.light", indices: "2/7" },
{ componentFolder: "accessibility/common", name: "accessibility - material (3/7)", theme: "material.blue.light", indices: "3/7" },
{ componentFolder: "accessibility/common", name: "accessibility - material (4/7)", theme: "material.blue.light", indices: "4/7" },
{ componentFolder: "accessibility/common", name: "accessibility - material (5/7)", theme: "material.blue.light", indices: "5/7" },
{ componentFolder: "accessibility/common", name: "accessibility - material (6/7)", theme: "material.blue.light", indices: "6/7" },
{ componentFolder: "accessibility/common", name: "accessibility - material (7/7)", theme: "material.blue.light", indices: "7/7" },
{ componentFolder: "accessibility/common", name: "accessibility - fluent (1/7)", theme: "fluent.blue.light", indices: "1/7" },
{ componentFolder: "accessibility/common", name: "accessibility - fluent (2/7)", theme: "fluent.blue.light", indices: "2/7" },
{ componentFolder: "accessibility/common", name: "accessibility - fluent (3/7)", theme: "fluent.blue.light", indices: "3/7" },
{ componentFolder: "accessibility/common", name: "accessibility - fluent (4/7)", theme: "fluent.blue.light", indices: "4/7" },
{ componentFolder: "accessibility/common", name: "accessibility - fluent (5/7)", theme: "fluent.blue.light", indices: "5/7" },
{ componentFolder: "accessibility/common", name: "accessibility - fluent (6/7)", theme: "fluent.blue.light", indices: "6/7" },
{ componentFolder: "accessibility/common", name: "accessibility - fluent (7/7)", theme: "fluent.blue.light", indices: "7/7" },
{ componentFolder: "accessibility/list", name: "accessibility - list (1/2)", indices: "1/2" },
{ componentFolder: "accessibility/list", name: "accessibility - list (1/2)", indices: "2/2" },
{ componentFolder: "accessibility/list", name: "accessibility - list - material (1/2)", theme: "material.blue.light", indices: "1/2" },
{ componentFolder: "accessibility/list", name: "accessibility - list - material (1/2)", theme: "material.blue.light", indices: "2/2" },
{ componentFolder: "accessibility/list", name: "accessibility - list - fluent (1/2)", theme: "fluent.blue.light", indices: "1/2" },
{ componentFolder: "accessibility/list", name: "accessibility - list - fluent (1/2)", theme: "fluent.blue.light", indices: "2/2" },
{ componentFolder: "common", name: "common" },
{ componentFolder: "common", name: "common - material", theme: 'material.blue.light' },
{ componentFolder: "common", name: "common - fluent", theme: 'fluent.blue.light' },
Expand All @@ -112,9 +118,10 @@ jobs:
{ componentFolder: "dataGrid/common", name: "dataGrid / common (3/5)", indices: "3/5" },
{ componentFolder: "dataGrid/common", name: "dataGrid / common (4/5)", indices: "4/5" },
{ componentFolder: "dataGrid/common", name: "dataGrid / common (5/5)", indices: "5/5" },
{ componentFolder: "dataGrid/stickyColumns", name: "dataGrid / sticky (1/3)", indices: "1/3" },
{ componentFolder: "dataGrid/stickyColumns", name: "dataGrid / sticky (2/3)", indices: "2/3" },
{ componentFolder: "dataGrid/stickyColumns", name: "dataGrid / sticky (3/3)", indices: "3/3" },
{ componentFolder: "dataGrid/sticky/common", name: "dataGrid / sticky common" },
{ componentFolder: "dataGrid/sticky/fixed", name: "dataGrid / sticky (1/3)", indices: "1/3" },
{ componentFolder: "dataGrid/sticky/fixed", name: "dataGrid / sticky (2/3)", indices: "2/3" },
{ componentFolder: "dataGrid/sticky/fixed", name: "dataGrid / sticky (3/3)", indices: "3/3" },
{ componentFolder: "pivotGrid", name: "pivotGrid", concurrency: 1 },
{ componentFolder: "pivotGrid", name: "pivotGrid - material", theme: 'material.blue.light', concurrency: 1 },
{ componentFolder: "pivotGrid", name: "pivotGrid - fluent", theme: 'fluent.blue.light', concurrency: 1 },
Expand Down
43 changes: 35 additions & 8 deletions e2e/testcafe-devextreme/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ const { globSync } = require('glob');
const testPageUtils = require('./helpers/clearPage');
require('nconf').argv();

const LAUNCH_RETRY_ATTEMPTS = 5;
const LAUNCH_RETRY_TIMEOUT = 20000;
const TESTCAFE_CONFIG = {
hostname: 'localhost',
port1: 1437,
port2: 1438,
// eslint-disable-next-line spellcheck/spell-checker
experimentalProxyless: true,
};

const changeTheme = async(t, themeName) => createTestCafe.ClientFunction(() => new Promise((resolve) => {
// eslint-disable-next-line no-undef
window.DevExpress.ui.themes.ready(resolve);
Expand All @@ -33,14 +43,31 @@ const addShadowRootTree = async(t) => {
}).with({ boundTestRun: t })();
};

const wait = async(timeout) => new Promise(resolve => setTimeout(resolve, timeout));

const retry = async(action, attempt) => {
return await action()
.catch(async(error) => {
if(attempt <= 1) {
throw error;
}

/* eslint-disable no-console */
console.log('\n > error occurred during testcafe launch!\n');
console.error(error);
console.info(`\n > waiting ${LAUNCH_RETRY_TIMEOUT / 1000} seconds...\n`);
await wait(LAUNCH_RETRY_TIMEOUT);
console.info('\n > retry launching testcafe\n');
/* eslint-enable no-console */
return await retry(action, attempt - 1);
});
};

let testCafe;
createTestCafe({
hostname: 'localhost',
port1: 1437,
port2: 1438,
// eslint-disable-next-line spellcheck/spell-checker
experimentalProxyless: true,
})

const initTestCafe = () => createTestCafe(TESTCAFE_CONFIG);

retry(initTestCafe, LAUNCH_RETRY_ATTEMPTS)
.then(tc => {
testCafe = tc;

Expand Down Expand Up @@ -186,7 +213,7 @@ function setShadowDom(args) {
function expandBrowserAlias(browser, componentFolder) {
switch(browser) {
case 'chrome:devextreme-shr2':
return 'chrome:headless --no-sandbox --disable-gpu --window-size=1200,800 --disable-partial-raster --disable-skia-runtime-opts --run-all-compositor-stages-before-draw --disable-new-content-rendering-timeout --disable-threaded-animation --disable-threaded-scrolling --disable-checker-imaging --disable-image-animation-resync --use-gl="swiftshader" --disable-features=PaintHolding --js-flags=--random-seed=2147483647 --font-render-hinting=none --disable-font-subpixel-positioning';
return 'chrome:headless --no-sandbox --disable-gpu --window-size=1200,800 --disable-partial-raster --disable-skia-runtime-opts --run-all-compositor-stages-before-draw --disable-new-content-rendering-timeout --disable-threaded-animation --disable-threaded-scrolling --disable-checker-imaging --disable-image-animation-resync --use-gl="swiftshader" --disable-features=PaintHolding --font-render-hinting=none --disable-font-subpixel-positioning';
case 'chrome:docker':
return 'chromium:headless --no-sandbox --disable-gpu --window-size=1200,800';
}
Expand Down
35 changes: 22 additions & 13 deletions packages/devextreme/docker-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function run_test_impl {
local runner_pid
local runner_result=0

[ -z "$CHROME_CMD"] && CHROME_CMD=google-chrome-stable
[ "$LOCAL" == "true" ] && url="http://host.docker.internal:$port/run?notimers=true"
[ -n "$CONSTEL" ] && url="$url&constellation=$CONSTEL"
[ -n "$MOBILE_UA" ] && url="$url&deviceMode=true"
Expand Down Expand Up @@ -96,23 +97,32 @@ function run_test_impl {
;;

*)
local chrome_command=google-chrome-stable
local chrome_command=$CHROME_CMD
local chrome_args=(
--no-sandbox
--disable-dev-shm-usage
--headless
--disable-gpu
--disable-partial-raster
--disable-skia-runtime-opts
--no-first-run
--run-all-compositor-stages-before-draw
--disable-new-content-rendering-timeout
--disable-background-timer-throttling
--disable-renderer-backgrounding
--disable-threaded-animation
--disable-threaded-scrolling
--disable-checker-imaging
--disable-image-animation-resync
--use-gl="swiftshader"
--disable-features=PaintHolding
--disable-features=ScriptStreaming
--disable-features=LazyFrameLoading
--font-render-hinting=none
--disable-font-subpixel-positioning
--disable-extensions
--user-data-dir=/tmp/chrome
)

if [ "$NO_HEADLESS" != "true" ]; then
echo "Headless mode"
chrome_args+=(
--headless
--remote-debugging-address=0.0.0.0
--remote-debugging-port=9222
)
else
if [ "$NO_HEADLESS" == "true" ]; then
chrome_command="dbus-launch --exit-with-session $chrome_command"
chrome_args+=(
--no-first-run
Expand All @@ -125,7 +135,6 @@ function run_test_impl {
echo "Performance tests"
chrome_args+=(
--disable-popup-blocking
--remote-debugging-port=9223
--enable-impl-side-painting
--enable-skia-benchmarking
--disable-web-security
Expand Down Expand Up @@ -163,7 +172,7 @@ function run_test_impl {
printf ' %s\n' "${chrome_args[@]}"
tput setaf 9
fi
google-chrome-stable --version
eval "$chrome_command --version"
eval "$chrome_command ${chrome_args[@]} '$url'" &>chrome.log &
;;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,8 @@ QUnit.module('Initialization', baseModuleConfig, () => {

// assert
assert.equal(toolbarItemOffset, $(dataGrid.$element()).find('.dx-datagrid-search-panel').offset().top, 'toolbar search panel is aligned');
assert.roughEqual(toolbarItemOffset, $(dataGrid.$element()).find('.dx-toolbar .dx-datebox').offset().top, 0.51, 'toolbar custom item is aligned');
// NOTE: Changed during Chrome133 update from 0.51 -> 1.51
assert.roughEqual(toolbarItemOffset, $(dataGrid.$element()).find('.dx-toolbar .dx-datebox').offset().top, 1.51, 'toolbar custom item is aligned');
});

QUnit.test('Column caption should have correct width when sorting is disabled (T1009923)', function(assert) {
Expand Down

0 comments on commit 9e9e975

Please sign in to comment.