https://gerrit.wikimedia.org/r/#/c/423648/3/tests/selenium/features/support/pages/mw_core_pages.js,unified reminded me of the import/export pattern we currently use. I thought I raised a bug around this but I can't find it.
Problem
Current the pattern we've started using for selenium tests in MediaWiki extensions looks like this:
let Page = require( '../../../../../../../tests/selenium/pageobjects/page.js' ), UserLoginPage = require( '../../../../../../../tests/selenium/pageobjects/userlogin.page.js' );
Issues:
- Hard to read.
- Hard to maintain for core: If the file structure changes in core, all extensions will break and require immediate updates. This might scale for the handful of wmf-deployed extensions using selenium tests now, but it won't scale to the larger ecosystem (compared to ESLint, Grunt or PHPUnit).
- Hard to get right for extensions: Even if core doesn't change, the pattern heavily relies on current depth on both sides, so a different location within the extension also requires the paths to be carefully updated.
- Not compatible with MediaWiki run-time support: This structure requires hardcoding paths based on how the extension is installed in Jenkins. But developers locally may use a different hierarchy (Extensions may be included/loaded in LocalSettings from anywhere. Even the built-in wfLoadExtension short-cut supports alternate roots via $wgExtensionDirectory).
- Unclear distinction between public and private. All files can be included from core's tests/selenium/pageobjects, there is no distiction between what is meant to be re-used and what isn't.
Solution
- Split a re-usable set of classes from corre's pageobjects directory into a new wdio-mediawiki directory.
- Register this directory in core's package.json file.
- Use that in extensions instead of the hardcoded file paths.
Basically:
{ "devDependencies": { "wdio-mediawiki": "file:tests/selenium/wdio-mediawiki" } }
Then, from an extension:
- let Page = require( '../../../../../../../tests/selenium/pageobjects/page.js' ); + let Page = require( 'wdio-mediawiki/Page' ); - let UserLoginPage = require( '../../../../../../../tests/selenium/pageobjects/userlogin.page.js' ); + let UserLoginPage = require( 'wdio-mediawiki/UserLoginPage' );
Given tests are run from core this should just work.