Skip to content

Commit

Permalink
refactor: improve IE and Windows support
Browse files Browse the repository at this point in the history
- Disable the brokenWindowSwitch test in IE (it hangs)
- Build browser tests as ES5
- Make loader scripts and RemoteSuite configuration script IE-friendly
- Add descriptive comments to tsconfig files
- Make webpack paths more Windows-friendly
- Make execute scripts IE-compatible
- Add a mouse click listener to one of the functional test pages to
  visualize click locations
- Add a pathRe function to create platform-compatible path-based regular
  expressions

references #1043
references #1037
  • Loading branch information
jason0x43 committed Jul 21, 2020
1 parent 08317c5 commit 556f18c
Show file tree
Hide file tree
Showing 17 changed files with 4,303 additions and 4,222 deletions.
8,251 changes: 4,135 additions & 4,116 deletions packages/core/docs/api.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion packages/core/src/lib/RemoteSuite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,13 @@ export default class RemoteSuite extends Suite {
// Send the config data in an execute block to avoid sending
// very large query strings
.execute(
// This script should be IE11-compatible
/* istanbul ignore next */ function (configString: string) {
const options = JSON.parse(configString);
intern.configure(options);
intern.run().catch(_error => {});
intern.run().catch(function () {
return undefined;
});
},
[stringify(remoteConfig)]
)
Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/loaders/default.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/**
* A loader script for loading non-module JavaScript suites.
*
* Note that loader scripts must be simple scripts, not modules.
* Note that loader scripts must be simple scripts, not modules, and must use
* IE11 compatible code (no arrow functions).
*/
intern.registerLoader(_config => {
intern.registerLoader(function () {
intern.log('Using default loader');

return (modules: string[]) => {
return function (modules: string[]) {
return intern.loadScript(modules);
};
});
19 changes: 10 additions & 9 deletions packages/core/src/loaders/dojo.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/**
* A loader script for setting up the Dojo loader.
*
* Note that loader scripts must be simple scripts, not modules.
* Note that loader scripts must be simple scripts, not modules, and must use
* IE11 compatible code (no arrow functions).
*/
intern.registerLoader(options => {
intern.registerLoader(function (options) {
const globalObj: any = typeof window !== 'undefined' ? window : global;

options.baseUrl = options.baseUrl || intern.config.basePath;
Expand All @@ -19,28 +20,28 @@ intern.registerLoader(options => {
intern.log('Configuring Dojo loader with:', options);
globalObj.dojoConfig = options;

return intern.loadScript('node_modules/dojo/dojo.js').then(() => {
return intern.loadScript('node_modules/dojo/dojo.js').then(function () {
const require = globalObj.require;
intern.log('Using Dojo loader');

return (modules: string[]) => {
return function (modules: string[]) {
let handle: { remove(): void };

return new Promise((resolve, reject) => {
handle = require.on('error', (error: Error) => {
return new Promise(function (resolve, reject) {
handle = require.on('error', function (error: Error) {
intern.emit('error', error);
reject(new Error(`Dojo loader error: ${error.message}`));
});

intern.log('Loading modules:', modules);
require(modules, () => {
require(modules, function () {
resolve();
});
}).then<void>(
() => {
function () {
handle.remove();
},
error => {
function (error) {
handle && handle.remove();
throw error;
}
Expand Down
63 changes: 33 additions & 30 deletions packages/core/src/loaders/dojo2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,43 @@
/**
* A loader script for setting up the Dojo loader.
*
* Note that loader scripts must be simple scripts, not modules.
* Note that loader scripts must be simple scripts, not modules, and must use
* IE11 compatible code (no arrow functions).
*/
intern.registerLoader(options => {
intern.registerLoader(function (options) {
const globalObj: any = typeof window !== 'undefined' ? window : global;
return intern.loadScript('node_modules/@dojo/loader/loader.js').then(() => {
const require: DojoLoader.RootRequire = globalObj.require;
intern.log('Using Dojo 2 loader');
return intern
.loadScript('node_modules/@dojo/loader/loader.js')
.then(function () {
const require: DojoLoader.RootRequire = globalObj.require;
intern.log('Using Dojo 2 loader');

options.baseUrl = options.baseUrl || intern.config.basePath;
intern.log('Configuring loader with:', options);
require.config(options);
options.baseUrl = options.baseUrl || intern.config.basePath;
intern.log('Configuring loader with:', options);
require.config(options);

return (modules: string[]) => {
let handle: { remove(): void };
return function (modules: string[]) {
let handle: { remove(): void };

return new Promise((resolve, reject) => {
handle = require.on('error', (error: Error) => {
intern.emit('error', error);
reject(error);
});
return new Promise(function (resolve, reject) {
handle = require.on('error', function (error: Error) {
intern.emit('error', error);
reject(error);
});

intern.log('Loading modules:', modules);
require(modules, () => {
resolve();
});
}).then<void>(
() => {
handle.remove();
},
error => {
handle && handle.remove();
throw error;
}
);
};
});
intern.log('Loading modules:', modules);
require(modules, function () {
resolve();
});
}).then<void>(
function () {
handle.remove();
},
function (error) {
handle && handle.remove();
throw error;
}
);
};
});
});
7 changes: 5 additions & 2 deletions packages/core/src/loaders/esm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ import Browser from '../lib/executors/Browser';

/**
* A loader script for loading ES-module JavaScript suites in the browser.
*
* Note that loader scripts must be simple scripts, not modules, and must use
* IE11 compatible code (no arrow functions).
*/
intern.registerLoader(_config => {
intern.registerLoader(function () {
if (intern.environment !== 'browser') {
throw new Error('The ESM loader only works in the browser');
}
Expand All @@ -13,7 +16,7 @@ intern.registerLoader(_config => {
// Declare a Browser-typed refernce to the global executor
const internBrowser: Browser = <any>intern;

return (modules: string[]) => {
return function (modules: string[]) {
return internBrowser.loadScript(modules, true);
};
});
15 changes: 9 additions & 6 deletions packages/core/src/loaders/systemjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
/**
* A loader script for setting up the SystemJS loader.
*
* Note that loader scripts must be simple scripts, not modules.
* Note that loader scripts must be simple scripts, not modules, and must use
* IE11 compatible code (no arrow functions).
*/

intern.registerLoader(options => {
intern.registerLoader(function (options) {
options.baseURL = options.baseURL || intern.config.basePath;
const globalObj: any = typeof window !== 'undefined' ? window : global;

if (intern.environment === 'browser') {
return intern
.loadScript('node_modules/systemjs/dist/system.src.js')
.then(() => {
.then(function () {
return configAndLoad(SystemJS);
});
} else {
Expand All @@ -28,11 +29,13 @@ intern.registerLoader(options => {
intern.log('Configuring SystemJS with:', options);
loader.config(options);

return (modules: string[]) => {
return function (modules: string[]) {
intern.log('Loading modules with SystemJS:', modules);
return modules.reduce((previous, suite) => {
return modules.reduce(function (previous, suite) {
if (previous) {
return previous.then(() => loader.import(suite));
return previous.then(function () {
return loader.import(suite);
});
}
return loader.import(suite);
}, <any>null);
Expand Down
12 changes: 10 additions & 2 deletions packages/core/tests/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,21 @@ const common: Configuration = {
}
}
],
noParse: /benchmark\/benchmark.js/
// benchmark's code makes webpack sad; tell webpack not to look at it
noParse: /benchmark\.js/
},
performance: {
// Hides a warning about large bundles.
hints: false
},
plugins: [new HotModuleReplacementPlugin(), new RewireMockPlugin()],

plugins: [
// Needed for mocking
new HotModuleReplacementPlugin(),
// Needed for mocking
new RewireMockPlugin()
],

resolve: {
extensions: ['.ts', '.js'],
plugins: [
Expand Down
12 changes: 7 additions & 5 deletions packages/core/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ const common: Configuration = {
}
}
],
noParse: /benchmark\/benchmark.js/
// benchmark's code makes webpack sad; tell webpack not to look at it
noParse: /benchmark\.js/
},
performance: {
// Hides a warning about large bundles.
Expand All @@ -56,15 +57,16 @@ module.exports = [
entry: getEntries(),
output: {
filename: '[name].js',
path: join(__dirname, 'dist/browser')
path: join(__dirname, 'dist', 'browser')
}
}
];

function getEntries() {
const baseDir = join(__dirname, 'src', 'browser');
return {
intern: './src/browser/intern.ts',
remote: './src/browser/remote.ts',
config: './src/browser/config.ts'
intern: join(baseDir, 'intern.ts'),
remote: join(baseDir, 'remote.ts'),
config: join(baseDir, 'config.ts')
};
}
9 changes: 9 additions & 0 deletions packages/digdug/tests/support/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { rm } from 'shelljs';
import Tunnel from '../../src/Tunnel';
import { sep } from 'path';

/**
* Cleans up a tunnel by stopping it if the tunnel is running and deleting its target install directory
Expand Down Expand Up @@ -47,3 +48,11 @@ export function getDigdugArgs() {
noClean: (<any>intern.config).noClean
};
}

export function pathRe(regex: string, flags?: string): RegExp {
if (sep !== '/') {
const winRegEx = regex.replace(/\//g, '\\\\');
return new RegExp(winRegEx, flags);
}
return new RegExp(regex, flags);
}
16 changes: 4 additions & 12 deletions packages/digdug/tests/unit/SauceLabsTunnel.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import SauceLabsTunnel from '../../src/SauceLabsTunnel';
import { sep } from 'path';

const reSep = sep === '\\' ? '\\\\' : sep;
import { pathRe } from '../support/util';

registerSuite('tunnels/SauceLabsTunnel', () => {
let tunnel: SauceLabsTunnel;
Expand All @@ -24,24 +22,18 @@ registerSuite('tunnels/SauceLabsTunnel', () => {

tunnel.platform = 'osx';
tunnel.architecture = 'foo';
let executable = new RegExp(
`${reSep}sc-\\d+\\.\\d+(?:\\.\\d+)?-osx${reSep}bin${reSep}sc$`
);
let executable = pathRe(`/sc-\\d+\\.\\d+(?:\\.\\d+)?-osx/bin/sc$`);
assert.match(tunnel.executable, executable);

tunnel.platform = 'linux';
assert.equal(tunnel.executable, 'java');

tunnel.architecture = 'x64';
executable = new RegExp(
`${reSep}sc-\\d+\\.\\d+(?:\\.\\d+)?-linux${reSep}bin${reSep}sc$`
);
executable = pathRe(`/sc-\\d+\\.\\d+(?:\\.\\d+)?-linux/bin/sc$`);
assert.match(tunnel.executable, executable);

tunnel.platform = 'win32';
executable = new RegExp(
`${reSep}sc-\\d+\\.\\d+(?:\\.\\d+)?-win32${reSep}bin${reSep}sc\\.exe$`
);
executable = pathRe(`/sc-\\d+\\.\\d+(?:\\.\\d+)?-win32/bin/sc\\.exe$`);
assert.match(tunnel.executable, executable);
},

Expand Down
13 changes: 8 additions & 5 deletions packages/leadfoot/src/Element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ export default class Element extends Locator<
click() {
if (this.session.capabilities.brokenClick) {
return this.session.execute<void>(
/* istanbul ignore next */ (element: HTMLElement) => {
/* istanbul ignore next */ function (element: HTMLElement) {
element.click();
},
[this]
Expand All @@ -271,7 +271,7 @@ export default class Element extends Locator<
submit() {
if (this.session.capabilities.brokenSubmitElement) {
return this.session.execute<void>(
/* istanbul ignore next */ (element: any) => {
/* istanbul ignore next */ function (element: any) {
if (element.submit) {
element.submit();
} else if (element.type === 'submit' && element.click) {
Expand All @@ -293,7 +293,7 @@ export default class Element extends Locator<
getVisibleText(): CancellablePromise<string> {
if (this.session.capabilities.brokenVisibleText) {
return this.session.execute<string>(
/* istanbul ignore next */ (element: any) => {
/* istanbul ignore next */ function (element: any) {
return element.innerText;
},
[this]
Expand Down Expand Up @@ -593,7 +593,7 @@ export default class Element extends Locator<
this.session.capabilities.brokenElementDisplayedOffscreen)
) {
return this.session.execute<boolean>(
/* istanbul ignore next */ (element: HTMLElement) => {
/* istanbul ignore next */ function (element: HTMLElement) {
const scrollX =
document.documentElement.scrollLeft || document.body.scrollLeft;
const scrollY =
Expand Down Expand Up @@ -707,7 +707,10 @@ export default class Element extends Locator<
getComputedStyle(propertyName: string): CancellablePromise<string> {
const manualGetStyle = () => {
return this.session.execute<string>(
/* istanbul ignore next */ (element: any, propertyName: string) => {
/* istanbul ignore next */ function (
element: any,
propertyName: string
) {
return (<any>window.getComputedStyle(element))[propertyName];
},
[this, propertyName]
Expand Down

0 comments on commit 556f18c

Please sign in to comment.