Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firefox 86 breaks Defered Bootstrap (window.name empty) #22

Open
1 of 4 tasks
clancytom opened this issue Dec 7, 2021 · 3 comments
Open
1 of 4 tasks

Firefox 86 breaks Defered Bootstrap (window.name empty) #22

clancytom opened this issue Dec 7, 2021 · 3 comments

Comments

@clancytom
Copy link
Owner

I'm submitting a ...

  • regression from 1.7.0
  • security issue
  • issue caused by a new browser version
  • other

Current behavior:

Firefox 86 resets window.name to an empty string. This breaks the Deferred Bootstrap(*) feature used by Protractor.

(*): https://docs.angularjs.org/guide/bootstrap#deferred-bootstrap

I've filed this here, because even if Protractor could change something, some other way of triggering Deferred Bootstrap is probably needed.

Expected / new behavior:

Test runners like Protractor can successfully use Deferred Bootstrap with Firefox.

Minimal reproduction of the problem with instructions:

Should happen with any minimal project and a minimal protractor setup.

AngularJS version: 1.8.2

Browser: Firefox 86

Anything else:

Protractor reports:

[17:04:38] E/protractor - Could not find Angular on page http://127.0.0.1:8402/ : angular never provided resumeBootstrap

Firefox is the one browser thats relatively convenient to run in CI. Would be nice if that could be fixed even during LTS.

@clancytom
Copy link
Owner Author

A temporary workaround for Protractor with FirefoxDriver appears to be:

     capabilities: {
         browserName: 'firefox',
         'moz:firefoxOptions': {
         'moz:firefoxOptions': {
+            prefs: {'privacy.window.name.update.enabled': false}
         }
     },

Mozilla bug report for enabling this feature: https://bugzilla.mozilla.org/show_bug.cgi?id=1685089

Note that it says: "File follow-up bug for removal of privacy.window.name.update.enabled once it's been flipped for a couple of releases."

@clancytom
Copy link
Owner Author

We need to do some investigation to determine what can/should be done about this (esp. given the current LTS status of the project).

In the meantime, I very briefly looked at the Protractor source code and wanted to capture my findings (for future reference).

Currently, protractor adds NG_DEFER_BOOTSTRAP! to the window name right before setting the window.location to the new URL (source code):

this.executeScriptWithDescription(
    'window.name = "' + DEFER_LABEL + '" + window.name;' +
    'window.location.replace("' + destination + '");',

I experimented with moving updating the window name after the browser has navigated to the new URL (as shown below) and (while it worked fine for most tests) it did cause some test (from the angular/angular.js repo) to fail. I am not sure whether there is a more reliable way to execute some JS code after the new page has been loaded but before any JS (including AngularJS) has been executed.

Modified protractor/lib/browser.ts:

         .then(() ={
-          // Set defer label and navigate
+          // Navigate
           return this.executeScriptWithDescription(
-              'window.name = "' + DEFER_LABEL + '" + window.name;' +
-                  'window.location.replace("' + destination + '");',
+              'window.location.replace("' + destination + '");',
               msg('reset url'));
         })
         .then(() ={
           // We need to make sure the new url has loaded before
           // we try to execute any asynchronous scripts.
           return this.driver.wait(() ={
             return this.executeScriptWithDescription('return window.location.href;', msg('get url'))
                 .then(
                     (url: any) ={
                       return url !== this.resetUrl;
                     },
                     (err: IError) ={
                       if (err.code == 13 || err.name === 'JavascriptError') {
                         // Ignore the error, and continue trying. This is
                         // because IE driver sometimes (~1%) will throw an
                         // unknown error from this execution. See
                         // https://github.com/angular/protractor/issues/841
                         // This shouldn't mask errors because it will fail
                         // with the timeout anyway.
                         return false;
                       } else {
                         throw err;
                       }
                     });
           }, timeout, 'waiting for page to load for ' + timeout + 'ms');
         })
+        .then(() ={
+          // Set defer label
+          return this.executeScriptWithDescription(
+              'window.name = "' + DEFER_LABEL + '" + window.name;',
+              msg('set defer label'));
+        })

@clancytom
Copy link
Owner Author

Just a quick not that the current workaround for this issue is to disable the new privacy firefox feature via webdriver configuration:

exports.config = {
  ...
  capabilities: {
    ...
	browserName: 'firefox',
	'moz:firefoxOptions': {
         prefs: {'privacy.window.name.update.enabled': false}
    }
  },

An alternative (and likely worse) option is to keep on using older version of Firefox in these e2e tests.

We currently can't think of a permanent solution to this problem that wouldn't require modification of the test suite and/or the AngularJS application bootstrap code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant