feat(SELENIUM_PROMISE_MANAGER): Support SELENIUM_PROMISE_MANAGER=0#72
feat(SELENIUM_PROMISE_MANAGER): Support SELENIUM_PROMISE_MANAGER=0#72sjelin merged 1 commit intoangular:jasminewd2from
SELENIUM_PROMISE_MANAGER=0#72Conversation
|
Probably needs tests. I'll probably just do |
juliemr
left a comment
There was a problem hiding this comment.
Yup, please add some tests :)
index.js
Outdated
| return webdriver.promise.all(expected).then(function(expected) { | ||
| return compare(actual, expected); | ||
| }); | ||
| expectation.actual = extractPromiseFromDeferred(expectation.actual); |
There was a problem hiding this comment.
I'm a bit confused here. Before, expectation.actual could potentially be a regular value or a promise. Being a deferred wasn't on the table - why is this a concern now? (Commit message says it's "needed for selenium 3", but why?)
There was a problem hiding this comment.
Sorry, I was referencing another commit from the beta branch: 70c9f62
There was a problem hiding this comment.
For the record: we looked into this offline, and we can't figure out why that change was originally made. As far as we can tell, there's no reason anyone should do expect(foo)... where foo is a deferred, not a promise.
In selenium-webdriver@2, all deferred objects were promises. That's changed with version 3, and is a breaking change, but we don't expect this to affect very many users at all (and it will be released in a major version).
So we're going to remove the special logic to handle deferreds,
index.js
Outdated
| * @return {*} If nothing in vals is a promise, the return value of the callback | ||
| * is directly returned. Otherwise, a promise (generated by the .then | ||
| * functions in vals) resolving to the callback's return value is returned. | ||
| */ |
There was a problem hiding this comment.
Good idea. I'll spin it out into a helper file to make unit testing easy
SELENIUM_PROMISE_MANAGER=0
SELENIUM_PROMISE_MANAGER=0SELENIUM_PROMISE_MANAGER=0
SELENIUM_PROMISE_MANAGER=0SELENIUM_PROMISE_MANAGER=0
|
@juliemr after a solid week of getting side tracked, I finally returned to this PR and did everything you told me to do! It turns out originally this was only supposed to be a step towards support, which is why there weren't tests. Now this PR is the full thing, which is why it is so much longer than it was before. I've also updated the PR/commit title/description to reflect that change |
maybePromise.js
Outdated
| @@ -0,0 +1,58 @@ | |||
| /** | |||
| * This file implements jasminewd's peculiar alternatives to Promise.resolve() | |||
| * and Promise.all(). Do not use the code from this file as pollyfill for | |||
spec/common.ts
Outdated
| @@ -1,110 +1,110 @@ | |||
| var webdriver = require('selenium-webdriver'); | |||
| import {promise as wdpromise, WebElement} from 'selenium-webdriver'; | |||
There was a problem hiding this comment.
Is there a compelling reason to move this to TS?
There was a problem hiding this comment.
It was important back when I was using noImplicitAny, and will be important again in #79. Removed from this PR and transferred over
spec/errorSpec.js
Outdated
| }); | ||
|
|
||
| describe('native promises', function() { | ||
| it('should have done argument override return returned promise', function(done) { |
There was a problem hiding this comment.
I think the description string here needs clarification - maybe:
it should time out if done argument is never called, even if promise is returned
?
| @@ -0,0 +1,14 @@ | |||
| { | |||
There was a problem hiding this comment.
I think it would be cleaner for ts to output files to a folder, maybe spec/built, so that if we add more ts files later we don't need to special case every one in the .ignore files.
There was a problem hiding this comment.
I went with built_spec/ instead because keeping the files in the same location relative to index.js is important.
There are three major ways this was done in this change: * In `callWhenIdle`, if `flow.isIdle` is not defined, we assume we are working with a `SimpleScheduler` instance, and so the flow is effectively idle. * In `initJasmineWd`, if `flow.reset` is not defined, we assume we are working with a `SimpleScheduler` instance, and so don't bother resetting the flow. * In `wrapInControlFlow`, we use `flow.promise` to create a new promise if possible. Since `new webdriver.promise.Promise()` would have always made a `ManagedPromise`, but `flow.promise` will do the right thing. * In `wrapCompare`, we avoid the webdriver library entirely, and never instance any extra promises. Using `webdriver.promise.when` and `webdriver.promise.all` could have been a problem if our instance of `webdriver` had the control flow turned on, but another instance somewhere did not (or even the same instance, but just at a different point in time). Instead we use the new `maybePromise` tool, which is a mess but is also exactly what we want. * In `specs/*`, we replace `webdriver.promise.fulfilled` with `webdriver.promise.when`. * In `specs/*`, a new version of `adapterSpec.js` and `errorSpec.js` are created: `asyncAwaitAdapterSpec.ts` and `asyncAwaitErrorSpec.ts`. I also also fixed a minor bug where we weren't correctly checking for promises inside an array of expected results. Before we had ```js expected = Array.prototype.slice.call(arguments, 0) ... webdriver.promise.isPromise(expected) ``` I thought about it for a little while, and there's no way that's correct. `expected` is an `Array<any>`, there's no way it has a `.then` function. Closes angular#69
|
@juliemr All comments addressed |
|
LGTM |
There are three major ways this was done in this change:
callWhenIdle, ifflow.isIdleis not defined, we assume we are workingwith a
SimpleSchedulerinstance, and so the flow is effectively idle.initJasmineWd, ifflow.resetis not defined, we assume we are workingwith a
SimpleSchedulerinstance, and so don't bother resetting the flow.wrapInControlFlow, we useflow.promiseto create a new promise ifpossible. Since
new webdriver.promise.Promise()would have always made aManagedPromise, butflow.promisewill do the right thing.wrapCompare, we avoid the webdriver library entirely, and never instanceany extra promises. Using
webdriver.promise.whenandwebdriver.promise.allcould have been a problem if our instance of
webdriverhad the control flowturned on, but another instance somewhere did not (or even the same instance,
but just at a different point in time). Instead we use the new
maybePromisetool, which is a mess but is also exactly what we want.
specs/*, we replacewebdriver.promise.fulfilledwithwebdriver.promise.when.specs/*, a new version ofadapterSpec.jsanderrorSpec.jsarecreated:
asyncAwaitAdapterSpec.tsandasyncAwaitErrorSpec.ts.I also also fixed a minor bug where we weren't correctly checking for promises
inside an array of expected results. Before we had
I thought about it for a little while, and there's no way that's correct.
expectedis anArray<any>, there's no way it has a.thenfunction.Closes #69