.nvmrc: Update now we're using Node 18, and make CI pass

* Babel upgraded to a version that works with new Node's OpenSSL.
* Various loaders upgraded to match
* Babel config changed as plugin-proposal-private-property-in-object is now official
* Webpack config updated as noEmitOnErrors was renamed to not be a negation
* Webpack config updated as namedModules was renamed to the wider moduleIds
* Ignore the built Webpack output from eslint

(cherry picked from commit 863c442c32)

----

Manually delete selenium tests, as they don't work and they're not worth the effort
of back-porting all the fixes to make them work.

Bug: T354943
Bug: T358102
Change-Id: Idcf164030bbc855a07acd4de45c57197ecc85095
This commit is contained in:
James D. Forrester 2024-01-12 13:41:53 -05:00
parent a310556d68
commit fc5d84d5ad
16 changed files with 2977 additions and 38818 deletions

View file

@ -4,7 +4,7 @@
["@babel/transform-runtime", {
"regenerator": true
}],
["@babel/plugin-proposal-private-property-in-object", {
["@babel/plugin-transform-private-property-in-object", {
"loose": true
}]
]

View file

@ -3,3 +3,5 @@
# docs and storybook
/docs/
/vendor/
# Compiled content
/resources/dist

2
.nvmrc
View file

@ -1 +1 @@
12.21.0
18.17.0

41435
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -14,46 +14,44 @@
"test:lint:i18n": "banana-checker --requireLowerCase=0 i18n/",
"check-built-assets": "echo 'CHECKING BUILD SOURCES ARE COMMITTED OR STAGED' && npm -s run build && git diff --exit-code resources/dist || { npm run node-debug; false; }",
"coverage": "nyc npm -s run test:unit",
"doc": "jsdoc -c jsdoc.json && npm run build-storybook",
"doc": "jsdoc -c jsdoc.json # SKIPPED! && npm run build-storybook",
"linter:js": "eslint --cache .",
"linter:styles": "stylelint 'src/**/*.less'",
"minify-svg": "svgo --config=.svgo.config.js --quiet --recursive --folder resources/ext.popups.images/",
"node-debug": "node -v && npm -v && echo 'Please ensure you are running the correct version of nvm before running this command.'",
"precommit": "npm -s t",
"selenium-daily": "npm run selenium-test",
"selenium-test": "wdio tests/selenium/wdio.conf.js"
"precommit": "npm -s t"
},
"engines": {
"node": "12.21.0"
"node": "18.17.0"
},
"devDependencies": {
"@babel/core": "7.2.0",
"@babel/core": "7.22.20",
"@babel/plugin-transform-private-property-in-object": "7.23.4",
"@babel/plugin-transform-runtime": "7.15.0",
"@babel/preset-env": "7.2.0",
"@babel/register": "7.0.0",
"@storybook/html": "6.4.22",
"@types/jquery": "3.3.29",
"@wdio/cli": "7.4.6",
"@wdio/dot-reporter": "7.4.2",
"@wdio/junit-reporter": "7.4.2",
"@wdio/local-runner": "7.4.6",
"@wdio/mocha-framework": "7.30.2",
"@wdio/sync": "7.4.6",
"@wikimedia/mw-node-qunit": "6.3.0",
"babel-loader": "8.0.4",
"@wdio/cli": "7.30.1",
"@wdio/junit-reporter": "7.29.1",
"@wdio/local-runner": "7.30.1",
"@wdio/mocha-framework": "7.26.0",
"@wdio/spec-reporter": "7.29.1",
"@wikimedia/mw-node-qunit": "7.0.0",
"babel-loader": "9.1.3",
"browserslist-config-wikimedia": "0.2.0",
"bundlesize": "0.18.1",
"clean-webpack-plugin": "3.0.0",
"cssjanus": "1.3.1",
"eslint": "8.31.0",
"eslint-config-wikimedia": "0.22.1",
"expose-loader": "0.7.5",
"expose-loader": "4.1.0",
"grunt-banana-checker": "0.10.0",
"jquery": "3.6.1",
"jsdoc": "3.6.10",
"less": "3.8.1",
"less-loader": "4.1.0",
"less-loader": "11.1.4",
"nyc": "15.0.0",
"postcss-less": "6.0.0",
"pre-commit": "1.2.2",
"redux": "4.0.1",
"redux-thunk": "2.3.0",
@ -61,10 +59,10 @@
"svg-inline-loader": "0.8.2",
"svgo": "2.8.0",
"tap-mocha-reporter": "5.0.1",
"url-loader": "1.1.2",
"wdio-mediawiki": "1.2.0",
"webpack": "4.44.2",
"webpack-cli": "3.3.12"
"url-loader": "4.1.1",
"wdio-mediawiki": "2.1.0",
"webpack": "5.89.0",
"webpack-cli": "5.1.4"
},
"bundlesize": [
{

Binary file not shown.

Binary file not shown.

View file

@ -1,9 +0,0 @@
{
"root": true,
"extends": [
"wikimedia/selenium"
],
"globals": {
"mw": "readonly"
}
}

View file

@ -1,21 +0,0 @@
# Selenium tests
For more information see https://www.mediawiki.org/wiki/Selenium
## Setup
See https://www.mediawiki.org/wiki/MediaWiki-Docker/Extension/Popups
## Run all specs
npm run selenium-test
## Run specific tests
Filter by file name:
npm run selenium-test -- --spec tests/selenium/specs/[FILE-NAME]
Filter by file name and test name:
npm run selenium-test -- --spec tests/selenium/specs/[FILE-NAME] --mochaOpts.grep [TEST-NAME]

View file

@ -1,21 +0,0 @@
=Popups test page=
==Valid links==
* [[Popups test page 2]]
==Invalid links==
# blah
==Reference links==
Lorem ipsum dolor.<ref>small reference</ref>
Reference with lots of text.<ref>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</ref>
Lorem ipsum dolor.<ref>reference inception<sup id="cite_ref-1" class="reference">[[#cite_note-1|[1]]]</sup></ref>
==Hash fragments==
[[#section]]
==References==
<references />
__NOTOC__

View file

@ -1,9 +0,0 @@
This page has a lead section.
=Popups test page 2=
==Valid links==
* [[Popups test page]]
==Invalid links==
# blah

View file

@ -1,143 +0,0 @@
'use strict';
/* global document */
const
fs = require( 'fs' ),
Api = require( 'wdio-mediawiki/Api' ),
Page = require( 'wdio-mediawiki/Page' ),
Util = require( 'wdio-mediawiki/Util' ),
TEST_PAGE_TITLE = 'Popups test page',
POPUPS_SELECTOR = '.mwe-popups',
PAGE_POPUPS_SELECTOR = '.mwe-popups-type-page',
PAGE_POPUPS_LINK_SELECTOR = '.mw-body-content ul a',
REFERENCE_POPUPS_SELECTOR = '.mwe-popups-type-reference',
REFERENCE_INCEPTION_LINK_SELECTOR = '.mwe-popups-type-reference .reference a',
POPUPS_MODULE_NAME = 'ext.popups.main';
function makePage( title, path ) {
return new Promise( ( resolve ) => {
fs.readFile( path, 'utf-8', ( err, content ) => {
if ( err ) {
throw err;
}
resolve( content );
} );
} ).then( async ( content ) => {
const bot = await Api.bot();
await bot.edit( title, content );
} );
}
class PopupsPage extends Page {
setup() {
browser.call( () => {
const path = `${__dirname}/../fixtures/`;
// FIXME: Cannot use Promise.all as wdio-mediawiki/Api will trigger a bad
// token error.
return makePage( `${TEST_PAGE_TITLE} 2`, `${path}/test_page_2.wikitext` ).then( () => {
return makePage( TEST_PAGE_TITLE, `${path}test_page.wikitext` );
} );
} );
}
ready() {
Util.waitForModuleState( POPUPS_MODULE_NAME );
}
shouldUseReferencePopupsBetaFeature( shouldUse ) {
Util.waitForModuleState( 'mediawiki.base' );
return browser.execute( function ( use ) {
return mw.loader.using( 'mediawiki.api' ).then( function () {
return new mw.Api().saveOptions( {
// TODO: Remove the first option when all Beta code is gone
popupsreferencepreviews: use ? '1' : '0',
'popups-reference-previews': use ? '1' : '0'
} );
} );
}, shouldUse );
}
hasReferencePopupsEnabled() {
// TODO Remove or adjust when not in Beta any more
return browser.execute( () => mw.config.get( 'wgPopupsReferencePreviews' ) );
}
abandonLink() {
$( '#content h1' ).moveTo();
}
dwellLink( selector, doesNotTriggerPreview ) {
$( selector ).moveTo();
if ( !doesNotTriggerPreview ) {
$( POPUPS_SELECTOR ).waitForExist();
} else {
browser.pause( 1000 );
}
}
dwellPageLink() {
this.dwellLink( PAGE_POPUPS_LINK_SELECTOR );
}
dwellPageFragment() {
this.dwellLink( '[href="#section"]', true );
}
hoverPageLink() {
$( PAGE_POPUPS_LINK_SELECTOR ).moveTo();
}
dwellReferenceLink( num ) {
this.dwellLink( `.reference:nth-of-type(${num}) a` );
}
dwellReferenceInceptionLink() {
$( REFERENCE_INCEPTION_LINK_SELECTOR ).moveTo();
browser.pause( 1000 );
}
doNotSeePreview( selector ) {
return browser.waitUntil( () => !$( selector ).isDisplayed() );
}
doNotSeePagePreview() {
return this.doNotSeePreview( PAGE_POPUPS_SELECTOR );
}
doNotSeeReferencePreview() {
return this.doNotSeePreview( REFERENCE_POPUPS_SELECTOR );
}
seePreview( selector ) {
return $( selector ).isDisplayed();
}
seePagePreview() {
return this.seePreview( PAGE_POPUPS_SELECTOR );
}
seeReferencePreview() {
return this.seePreview( REFERENCE_POPUPS_SELECTOR );
}
seeReferenceInceptionPreview() {
return this.seePreview( REFERENCE_INCEPTION_LINK_SELECTOR );
}
seeScrollableReferencePreview() {
return browser.execute( () => {
const el = document.querySelector( '.mwe-popups-extract .mwe-popups-scroll' );
return el.scrollHeight > el.offsetHeight;
} );
}
seeFadeoutOnReferenceText() {
return $( '.mwe-popups-fade-out' ).isExisting();
}
open() {
super.openTitle( TEST_PAGE_TITLE );
}
}
module.exports = new PopupsPage();

View file

@ -1,38 +0,0 @@
'use strict';
const assert = require( 'assert' ),
page = require( '../pageobjects/popups.page' );
describe( 'Dwelling on a valid page link', function () {
before( function () {
page.setup();
} );
beforeEach( function () {
page.open();
page.ready();
} );
it( 'I should see a page preview', function () {
page.dwellPageLink();
assert( page.seePagePreview(), 'Page preview is shown.' );
} );
it( 'I should not see a page preview on hash fragment', function () {
page.dwellPageFragment();
assert( page.doNotSeePagePreview(), 'Page preview is not shown.' );
} );
it( 'Abandoning link hides page preview', function () {
page.dwellPageLink();
page.abandonLink();
assert( page.doNotSeePagePreview(), 'Page preview is kept hidden.' );
} );
it( 'Quickly hovering, abandoning and re-hovering a link shows page preview', function () {
page.hoverPageLink();
page.abandonLink();
page.dwellPageLink();
assert( page.seePagePreview(), 'Page preview is shown.' );
} );
} );

View file

@ -1,56 +0,0 @@
'use strict';
const assert = require( 'assert' ),
page = require( '../pageobjects/popups.page' ),
UserLoginPage = require( 'wdio-mediawiki/LoginPage' );
describe( 'Dwelling on a valid reference link', function () {
before( function () {
page.setup();
// TODO Remove or adjust when not in Beta any more
UserLoginPage.loginAdmin();
page.shouldUseReferencePopupsBetaFeature( true );
} );
beforeEach( function () {
page.open();
page.ready();
} );
it( 'I should see a reference preview', function () {
if ( !page.hasReferencePopupsEnabled() ) {
this.skip();
}
page.dwellReferenceLink( 1 );
assert( page.seeReferencePreview(), 'Reference preview is shown.' );
assert( !page.seeScrollableReferencePreview(), 'Reference preview is not scrollable.' );
assert( !page.seeFadeoutOnReferenceText(), 'Reference preview has no fading effect' );
} );
it( 'Abandoning link hides reference preview', function () {
if ( !page.hasReferencePopupsEnabled() ) {
this.skip();
}
page.dwellReferenceLink( 1 );
page.abandonLink();
assert( page.doNotSeeReferencePreview(), 'Reference preview is kept hidden.' );
} );
it( 'References with lots of text are scrollable and fades', function () {
if ( !page.hasReferencePopupsEnabled() ) {
this.skip();
}
page.dwellReferenceLink( 2 );
assert( page.seeScrollableReferencePreview(), 'Reference preview is scrollable' );
assert( page.seeFadeoutOnReferenceText(), 'Reference preview has a fading effect' );
} );
it( 'Dwelling references links inside reference previews does not close the popup ', function () {
if ( !page.hasReferencePopupsEnabled() ) {
this.skip();
}
page.dwellReferenceLink( 3 );
page.dwellReferenceInceptionLink();
assert( page.seeReferenceInceptionPreview(), 'The reference preview is still showing.' );
} );
} );

View file

@ -1,11 +0,0 @@
'use strict';
const { config } = require( 'wdio-mediawiki/wdio-defaults.conf.js' );
exports.config = { ...config
// Override, or add to, the setting from wdio-mediawiki.
// Learn more at https://webdriver.io/docs/configurationfile/
//
// Example:
// logLevel: 'info',
};

View file

@ -20,7 +20,7 @@ module.exports = ( env, argv ) => ( {
},
// Fail on the first build error instead of tolerating it for prod builds. This seems to
// correspond to optimization.noEmitOnErrors.
// correspond to optimization.emitOnErrors.
bail: argv.mode === 'production',
// Specify that all paths are relative the Webpack configuration directory not the current
@ -67,14 +67,14 @@ module.exports = ( env, argv ) => ( {
},
optimization: {
// Don't produce production output when a build error occurs.
noEmitOnErrors: argv.mode === 'production',
emitOnErrors: argv.mode !== 'production',
// Use filenames instead of unstable numerical identifiers for file references. This
// increases the gzipped bundle size some but makes the build products easier to debug and
// appear deterministic. I.e., code changes will only alter the bundle they're packed in
// instead of shifting the identifiers in other bundles.
// https://webpack.js.org/guides/caching/#deterministic-hashes (namedModules replaces NamedModulesPlugin.)
namedModules: true
moduleIds: 'named'
},
output: {