This is a complete rework of our testing infrastructure. The main goal is to modernize and drop deprecated or undermaintained dependencies (specifically, grunt, karma, and testswarm). We've achieved that by limiting our dependency list to ones that are unlikely to drop support any time soon. The new dependency list includes:
- `qunit` (our trusty unit testing library)
- `selenium-webdriver` (for spinning up local browsers)
- `express` (for starting a test server and adding middleware)
- express middleware includes uses of `body-parser` and `raw-body`
- `yargs` (for constructing a CLI with pretty help text)
- BrowserStack (for running each of our QUnit modules separately in all of our supported browsers)
- `browserstack-local` (for opening a local tunnel. This is the same package still currently used in the new Browserstack SDK)
- We are not using any other BrowserStack library. The newest BrowserStack SDK does not fit our needs (and isn't open source). Existing libraries, such as `node-browserstack` or `browserstack-runner`, either do not quite fit our needs, are under-maintained and out-of-date, or are not robust enough to meet all of our requirements. We instead call the [BrowserStack REST API](https://github.com/browserstack/api) directly.
**BrowserStack**
- automatically retries individual modules in case of test failure(s)
- automatically attempts to re-establish broken tunnels
- automatically refreshes the page in case a test run has stalled
- Browser workers are reused when running isolated modules in the same browser
- runs all browsers concurrently and uses as many sessions as are available under the BrowserStack plan. It will wait for available sessions if there are none.
- supports filtering the available list of browsers by browser name, browser version, device, OS, and OS version (see `npm run test:unit -- --list-browsers` for more info). It will retrieve the latest matching browser available if any of those parameters are not specified. Supports latest and latest-\d+ in place of browser version.
- cleans up after itself (closes the local tunnel, stops the test server, etc.)
- Requires `BROWSERSTACK_USERNAME` and `BROWSERSTACK_ACCESS_KEY` environment variables.
**Selenium**
- supports running any local browser as long as the driver is installed, including support for headless mode in Chrome, FF, and Edge
- supports running `basic` tests on the latest [jsdom](https://github.com/jsdom/jsdom#readme), which can be seen in action in this PR (see `test:browserless`)
- Node tests will run as before in PRs and all non-dependabot branches, but now includes tests on real Safari in a GH actions macos image instead of playwright-webkit.
- can run multiple browsers and multiple modules concurrently
Other notes:
- Stale dependencies have been removed and all remaining dependencies have been upgraded with a few exceptions:
- `sinon`: stopped supporting IE in version 10. But, `sinon` has been updated to 9.x.
- `husky`: latest does not support Node 10 and runs on `npm install`. Needed for now until git builds are migrated to GitHub Actions.
- `rollup`: latest does not support Node 10. Needed for now until git builds are migrated to GitHub Actions.
- BrowserStack tests are set to run on each `main` branch commit
- `debug` mode leaves Selenium browsers open whether they pass or fail and leaves browsers with test failures open on BrowserStack. The latter is to avoid leaving open too many sessions.
- This PR includes a workflow to dispatch BrowserStack runs on-demand
- The Node version used for most workflow tests has been upgraded to 20.x
- updated supportjQuery to 3.7.1
Run `npm run test:unit -- --help` for CLI documentation
Close gh-5427
Remove a redundant Express-targeted `resp.set` call from the `script` handler
in `middleware-mockserver.js` as was done on the `main` branch.
Closes gh-5413
Ref gh-5397
- also add the ability to pass VERSION in env to test final builds
- adjust sha regex to account for lack of shas
- set the version on the dist package.json
Close gh-5408
Without this change, dependabot PRs run double checks - one set for the `push`
part and one for the `pull_request` part.
Closes gh-5353
(cherry picked from commit 635cb152e7)
If the iframe is not initially visible, the `scrollboxSize` support test is
failing. jQuery then cached this value and and applied the wrong result
undefinitely.
This breaks jQuery UI's Dialogs inside initially invisible iframes.
Closes gh-5317
Ref jquery/jquery-ui#2176
Build was already happening in scripts like `test:browser` but those scripts
were missing `pretest`, meaning that running `npm install && npm test:browser`
may have failed if `pretest` wasn't run before or if its results were out of
date.
Even worse, with such stale data some tests may erroneously succeed.
This also removes a separate `pretest` step from GitHub Actions as it's no
longer needed.
Closes gh-5338
(cherry picked from commit 1ad66aeb6d)
Close gh-5330
- lint
- npmcopy
- build, minify, and process for distribution.
- new custom build command using yargs
- compare size of minified/gzip built files
- pretest scripts, including qunit-fixture, babel transpilation, and npmcopy
- node smoke tests
- promises aplus tests
- new watch task using nodemon, which runs `npm run build:all` on `src` changes.
Also:
- upgraded husky and added the new lint command
- updated lint config to use new "flat" config format.
See https://eslint.org/docs/latest/use/configure/configuration-files-new
- Temporarily disabled one lint rule until flat config is
supported by eslint-plugin-import.
See https://github.com/import-js/eslint-plugin-import/issues/2556
- committed package-lock.json
- updated all test scripts to use the new build
- added an express test server that uses middleware-mockserver
this can be used to run tests without karma
- build-all-variants is now build:all
- run pretest script in jenkins
---------
Co-authored-by: Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
Summary of the changes:
* Tests: Remove legacy jQuery.cache & oldIE leftovers
* Tests: Reformat JavaScript in delegatetest.html
* Docs: "jQuery Foundation Projects" -> "jQuery Projects"
* Tests: Drop an unused localfile.html file (modern browsers don't support
the `file:` protocol this way, there's no point in keeping the file around)
* Effects: Remove a redundant `!fn` check (`fn || !fn && easing` is equivalent
to `fn || easing`; simplify the code)
* CSS: Explain the fallback to direct object access in curCSS better
* Tests: Deduplicate `jQuery.parseHTML` test titles
* Dimensions: Add a test for fractional values
* Tests: Fix a buggy WebKit regex
Closes gh-5296
(cherry picked from commit 93ca49e6d1)
Summary of the changes:
* expand `node_smoke_tests` to test the full & slim builds
* run `compare_size` on all built minified files; don't run it anymore on
unminified files where they don't provide lots of value
The main goal of this change is to make it easier to compare sizes of both the
full & slim builds between the `3.x-stable` & `main` branches.
Closes gh-5291
Ref gh-5255
(partially cherry-picked from commit 8be4c0e4f8)
Bootstrap 5 includes the following CSS on the page:
```css
*,
*::before,
*::after {
box-sizing: border-box;
}
```
That threw our `reliableTrDimensions` support test off. This change fixes the
support test and adds a unit test ensuring support test values on a page
including Bootstrap 5 CSS are the same as on a page without it.
Fixes gh-5270
Closes gh-5279
Ref gh-5278
Both IE & Edge Legacy need the workaround of calling `setDocument()` in an
`unload` handler to avoid "permission denied" errors. However, due to not being
possible to feature-detect this issue, the handler has been applied in all
browsers for windows different than the one in which jQuery was loaded.
jQuery 4.0, which drops Edge Legacy support, guards this workaround with
a `document.documentMode` check. This won't work in the 3.x line due to still
supporting Edge Legacy but we can check for
`document.documentElement.msMatchesSelector` instead as that API is
supported in IE 9+ and all Edge Legacy versions.
Fixes gh-5281
Closes gh-5282
Ref gh-4792
`Sizzle.tokenize` is an internal Sizzle API, but exposed. As a result,
it has historically been available in jQuery via `jQuery.find.tokenize`.
That got dropped during Sizzle removal; this change restores the API.
In addition to that, Sizzle tests have been backported for the following
APIs:
* `jQuery.find.matchesSelector`
* `jQuery.find.matches`
* `jQuery.find.compile`
* `jQuery.find.select`
A new test was also added for `jQuery.find.tokenize` - even Sizzle was
missing one.
Fixes gh-5259
Closes gh-5260
Ref gh-5263
Ref jquery/sizzle#242
Ref gh-5113
Ref gh-4395
Ref gh-4406
Now that unit tests are run on GitHub Actions in all three major
engines and for multiple custom jQuery builds, the request for PR
authors to run unit tests locally and confirm they pass is needless
overhead; let's drop the checkbox.
Closes gh-5261
(cherry picked from commit 988a56847d)
Make the deprecated `.hover()` method not rely on other deprecated
methods: `.mouseenter()` & `.mouseleave()`. Use `.on()` instead.
Closes gh-5251
(cherry picked from commit fd6ffc5eb2)
Chrome 112 & Safari 16.4 introduce two changes:
* `:has()` is non-forgiving
* `CSS.supports( "selector(...)" )` parses everything in a non-forgiving way
We no longer care about the latter but the former means the `cssHas` support
test now passes.
Closes gh-5226
This regressed in gh-3656 as the added logic to include scroll gutters
in `.innerWidth()` / `.innerHeight()` didn't take negative margins into
account. This broke handling of negative margins in
`.offsetHeight( true )` and `.offsetWidth( true )`. To fix it, calculate
margin delta separately and only add it after the scroll gutter
adjustment logic.
Fixes gh-3982
Closes gh-5234
Ref gh-3656
(cherry picked from commit bce13b72c1)
Previously, when `leverageNative` handled async events, there was
a case where an empty placeholder object was set as a result.
Covering both such an object and `false` required a `length` check.
However, this is not necessary since gh-5223 and the check was
already simplified in other places; this one was missed.
Closes gh-5236
Ref gh-5223
(cherry picked from commit dfe212d5a1)
There was a comment claiming that there are two implementations
of `safeActiveElement`. However, the one in `event.js` got removed
in gh-5224, even before the comment was added.
This commit removes this obsolete comment.
Closes gh-5237
Ref gh-5224
In IE 9 accessing `document.activeElement` may throw; see
https://bugs.jquery.com/ticket/13393. We've already guarded
against this in event code but not in selector.
Closes gh-5229
In `leverageNative`, instead of calling `event.stopImmediatePropagation()`
which would abort both native & jQuery handlers, set the wrapper's
`isImmediatePropagationStopped` property to a function returning `true`.
Since for each element + type pair jQuery attaches only one native handler,
there is also only one wrapper jQuery event so this achieves the goal:
on the target element jQuery handlers don't fire but native ones do.
Unfortunately, this workaround doesn't work for handlers on ancestors
- since the native event is re-wrapped by a jQuery one on each level of
the propagation, the only way to stop it for jQuery was to stop it for
everyone via native `stopPropagation()`. This is not a problem for
`focus`/`blur` which don't bubble, but it does also stop `click` on
checkboxes and radios. We accept this limitation.
Fixes gh-5015
Closes gh-5228
(cherry picked from commit 6ad3651dbf)