Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

Commit

Permalink
fix(globals): Resolve exported globals dynamically. (#3716)
Browse files Browse the repository at this point in the history
fixes #3677

Because globals are set in the runner, they may be undefined at import time. Also, the browser global object will change if browser.reset() is called. By making these globals exported as properties, they will be resolved dynamically. This also fixes issues importing protractor in config files written in typescript, since the globals are resolved at call time instead of at import time.

Note that until the Runner calls setupGlobals_, these exports will be undefined. That's just the nature of these objects, though, and the global objects have the same behavior.
  • Loading branch information
heathkit authored Nov 9, 2016
1 parent a1c8a23 commit f42e0b3
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 19 deletions.
2 changes: 1 addition & 1 deletion lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ export interface Config {
/**
* Set the randomization seed if randomization is turned on
*/
seed?: string,
seed?: string,
};

/**
Expand Down
38 changes: 28 additions & 10 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export let utils = {
firefox: require('selenium-webdriver/firefox'),
http: require('selenium-webdriver/http'),
remote: require('selenium-webdriver/remote')
}
};

export let Command = require('selenium-webdriver/lib/command').Command;
export let CommandName = require('selenium-webdriver/lib/command').Name;
Expand All @@ -32,12 +32,30 @@ export let CommandName = require('selenium-webdriver/lib/command').Name;
// We base this on NodeJS `global` because we do not want to mask
// with a different instance of Protractor if the module is
// installed both globally and locally.
export let protractor: Ptor = (global as any)['protractor'];
export let browser: ProtractorBrowser = protractor ? protractor.browser : undefined;
export let $: (search: string) => ElementFinder = protractor ? protractor.$ : undefined;
export let $$: (search: string) => ElementArrayFinder = protractor ? protractor.$$ : undefined;
export let element: ElementHelper = protractor ? protractor.element : undefined;
export let By: ProtractorBy = protractor ? protractor.By : undefined;
export let by: ProtractorBy = protractor ? protractor.by : undefined;
export let ExpectedConditions: ProtractorExpectedConditions =
protractor ? protractor.ExpectedConditions : undefined;

// Because these properties are set dynamically by the runner in setupGlobals_, they are not
// guaranteed to be created at import time. Also, the browser object can change if browser.reset()
// is called. Thus, we export these as properties so they will be resolved dynamically.
export declare let protractor: Ptor;
Object.defineProperty(exports, 'protractor', {get: () => (global as any)['protractor']});

function registerGlobal(name: string) {
Object.defineProperty(
exports, name, {get: () => exports.protractor ? exports.protractor[name] : undefined});
}

export declare let browser: ProtractorBrowser;
export declare let $: (search: string) => ElementFinder;
export declare let $$: (search: string) => ElementArrayFinder;
export declare let element: ElementHelper;
export declare let By: ProtractorBy;
export declare let by: ProtractorBy;
export declare let ExpectedConditions: ProtractorExpectedConditions;

registerGlobal('browser');
registerGlobal('$');
registerGlobal('$$');
registerGlobal('element');
registerGlobal('By');
registerGlobal('by');
registerGlobal('ExpectedConditions');
9 changes: 1 addition & 8 deletions lib/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,14 +254,7 @@ export class Runner extends EventEmitter {
// Note: because tests are not paused at this point, any async
// calls here are not guaranteed to complete before the tests resume.
this.driverprovider_.quitDriver(browser_.driver);
// Copy mock modules, but do not navigate to previous URL.
let forkBrowser = browser_.forkNewDriverInstance(false, true);

// Replace the items in browser_ but do not create a new object
// since this will break typescript imports
for (let item in forkBrowser) {
browser_[item] = forkBrowser[item];
}
browser_ = browser_.forkNewDriverInstance(false, true);
this.setupGlobals_(browser_);
};

Expand Down
14 changes: 14 additions & 0 deletions spec/basic/restart_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
describe('browser.restart', function() {
it('doesn\'t break ignoreSynchronization', function() {
browser.get('index.html#/polling');
browser.restart();

browser.ignoreSynchronization = true;
// Get a non-angular page. It shouldn't fail if ignoreSynchronization is on.
browser.get('https://google.com/');
});

afterAll(() => {
browser.ignoreSynchronization = false;
});
});

0 comments on commit f42e0b3

Please sign in to comment.