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

browser.restart should return a promise which resolves when the new browser is ready #3899

Closed
sjelin opened this issue Dec 30, 2016 · 4 comments

Comments

@sjelin
Copy link
Contributor

sjelin commented Dec 30, 2016

Proposed implementation:

browser_.restart = () => {
  let quitPromise = this.driverprovider_.quitDriver(browser_.driver);
  function forkAndOverwrite() { ... }
  if (wdpromise.USE_PROMISE_MANAGER !== false) {
    forkAndOverwrite();
  } else {
    quitPromise = quitPromise.then(forkAndOverwrite);
  }
  return quitPromise.then(() => {
    return browser_.ready();
  });
};

I know this is messy but:

  • Should the control flow be on, the fork/overwrite needs to be synchronous to support code like:

    browser.restart();
    browser.get('http://www.google.com'); // Must go to new instance
  • Should the control flow be off, we shouldn't do the fork/overwrite until after we've quit, or else we'll briefly have two browser instances floating around. Also, it'd just be weird and unexpected for the global browser instance to change synchronously when you're used to nothing happening until you await it.

@sjelin sjelin changed the title browser.restart should return a problem which resolves when the new browser is ready browser.restart should return a promise which resolves when the new browser is ready Dec 30, 2016
@sjelin
Copy link
Contributor Author

sjelin commented Dec 30, 2016

Blocked on #3902

sjelin added a commit to sjelin/protractor that referenced this issue Jan 20, 2017
Wrapping it in a `q` promise is blocking angular#3899

Closes angular#3902

Custom frameworks might not make this change but it'll be fine.  It'll only be a
problem in edge cases and they probably weren't returning the right promise
before anyway.
sjelin added a commit that referenced this issue Jan 20, 2017
#3992)

Wrapping it in a `q` promise is blocking #3899

Closes #3902

Custom frameworks might not make this change but it'll be fine.  It'll only be a
problem in edge cases and they probably weren't returning the right promise
before anyway.
@sjelin
Copy link
Contributor Author

sjelin commented Jan 21, 2017

Better solution to the original problem:

browser_.restart = () => {
  const driverPromise: wdpromise.Promise<WebDriver> = browser_.ready().then(() => {
    return this.driverprovider_.quitDriver(browser_.driver);
  }).then<WebDriver>(() => {
    return browser_.forkNewUnwrappedDriverInstance(false, true);
  });

  const flow = browser.driver.controlFlow();
  const executor = browser.driver.getExecutor();
  const session = driverPromise.then(driver => driver.getSession());
  const onQuit = extractOnQuit(driverPromise);
  browser_.setDriver_(new WebDriver(session, executor, flow, onQuit));
  return browser_.ready();
};

Unfortunately, the only extractOnQuit implementation I can think of is horrible:

function extractOnQuit(driverPromise: wdpromise.Promise<WebDriver>) {
  return function() {
    const args = arguments;
    return driverPromise.then((driver) => {
      if ((driver as any).onQuit_) {
        return (driver as any).onQuit_.apply(this, args);
      } else {
        const originalSchedule = driver.schedule;
        driver.schedule = () => driver.flow.promise<void>(resolve => resolve());
        const result = driver.quit().catch(function() {}); // catch any errors from double quit
        driver.schedule = originalSchedule;
      }
    });
  };
}

This implementation is actually even worse than it looks, because it makes onQuit more asynchronous than it originally was and can mask errors generated by onQuit. But it will basically get the job done.

Using a new setDriver_ method will be very helpful though, eliminating the need to call setupGlobals_ multiple times and fixing #3896 cleanly

@juliemr
Copy link
Member

juliemr commented Jan 23, 2017

I think I like the clarity of just splitting based on control flow. If we use setDriver_ behind the scenes, could we do something like:

// in runner.ts

browser_.restart = () => {
  if (wdpromise.USE_PROMISE_MANAGER === false) {
    let myPromise = this.driverprovider_.quitDriver(browser._driver).then(() => {
      return this.driverprovider_.getNewDriver();
    }).then((wd) => {
      return browser_.setDriver_(newDriver);
    }).then(() => {
     return driver.manage().timeouts().setScriptTimeout(this.config_.allScriptsTimeout);
    });
    return myPromise;
  } else {
    // we're using the control flow
    this.driverprovider_.quitDriver(browser._driver);
    browser_.setDriver(this.driverprovider_.getNewDriver());
    return driver.manage().timeouts().setScriptTimeout(this.config_.allScriptsTimeout);
  }
}

This should work with the control flow off - we return a promise which does everything we need. With the control flow on, we've set the driver synchronously, so commands which come next should be scheduled sensibly on the new driver.

sjelin added a commit to sjelin/protractor that referenced this issue Jan 23, 2017
Also allows `browser.restart` to work when the control flow is disabled, and
fixes it for forked browsers.

Closes angular#3899 and
angular#3896
sjelin added a commit to sjelin/protractor that referenced this issue Jan 23, 2017
Also allows `browser.restart` to work when the control flow is disabled, and
fixes it for forked browsers.

Closes angular#3899 and
angular#3896
sjelin added a commit that referenced this issue Jan 23, 2017
#3992)

Wrapping it in a `q` promise is blocking #3899

Closes #3902

Custom frameworks might not make this change but it'll be fine.  It'll only be a
problem in edge cases and they probably weren't returning the right promise
before anyway.
sjelin added a commit to sjelin/protractor that referenced this issue Jan 25, 2017
Also allows `browser.restart` to work when the control flow is disabled, and
fixes it for forked browsers.

Closes angular#3899 and
angular#3896
sjelin added a commit to sjelin/protractor that referenced this issue Jan 26, 2017
Also allows `browser.restart` to work when the control flow is disabled, and
fixes it for forked browsers.

Closes angular#3899 and
angular#3896
sjelin added a commit that referenced this issue Jan 26, 2017
Also allows `browser.restart` to work when the control flow is disabled, and
fixes it for forked browsers.

Closes #3899 and
#3896
sjelin added a commit that referenced this issue Jan 26, 2017
#3992)

Wrapping it in a `q` promise is blocking #3899

Closes #3902

Custom frameworks might not make this change but it'll be fine.  It'll only be a
problem in edge cases and they probably weren't returning the right promise
before anyway.
sjelin added a commit that referenced this issue Jan 26, 2017
Also allows `browser.restart` to work when the control flow is disabled, and
fixes it for forked browsers.

Closes #3899 and
#3896
sjelin added a commit to sjelin/protractor that referenced this issue Jan 27, 2017
angular#3992)

Wrapping it in a `q` promise is blocking angular#3899

Closes angular#3902

Custom frameworks might not make this change but it'll be fine.  It'll only be a
problem in edge cases and they probably weren't returning the right promise
before anyway.
@sjelin sjelin closed this as completed in b77cb92 Jan 27, 2017
@sjelin
Copy link
Contributor Author

sjelin commented Feb 8, 2017

For the record, browser_.setDriver ended up introducing some new problems, and we scrapped the idea in an offline discussion.

igniteram pushed a commit to igniteram/protractor that referenced this issue Feb 21, 2017
angular#3992)

Wrapping it in a `q` promise is blocking angular#3899

Closes angular#3902

Custom frameworks might not make this change but it'll be fine.  It'll only be a
problem in edge cases and they probably weren't returning the right promise
before anyway.
igniteram pushed a commit to igniteram/protractor that referenced this issue Feb 21, 2017
Also allows `browser.restart` to work when the control flow is disabled, and
fixes it for forked browsers.

Closes angular#3899 and
angular#3896
bodyduardU pushed a commit to bodyduardU/protractor that referenced this issue Dec 5, 2022
…y (#3992)

Wrapping it in a `q` promise is blocking angular/protractor#3899

Closes angular/protractor#3902

Custom frameworks might not make this change but it'll be fine.  It'll only be a
problem in edge cases and they probably weren't returning the right promise
before anyway.
bodyduardU pushed a commit to bodyduardU/protractor that referenced this issue Dec 5, 2022
Also allows `browser.restart` to work when the control flow is disabled, and
fixes it for forked browsers.

Closes angular/protractor#3899 and
angular/protractor#3896
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants