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

Protractor synchronization fails if multiple versions of selenium-webdriver are in node_modules #3505

Closed
ghost opened this issue Aug 31, 2016 · 21 comments
Assignees
Milestone

Comments

@ghost
Copy link

ghost commented Aug 31, 2016

Bug report

Setup

  • Node Version: 6.3.1
  • npm Version: 3.10.3
  • Protractor Version: 4.0.4 & 4.0.3
  • Browser(s): Chrome (52.0.2743.116 (Official Build) (64-bit))
  • Operating System and Version Ubuntu 16.04
  • Protractor configuration file
var SpecReporter = require('jasmine-spec-reporter');

exports.config = {
    allScriptsTimeout: 11000,
    specs: [
        '../e2e/**/*.e2e-spec.ts'
    ],
    capabilities: {
        'browserName': 'chrome'
    },
    directConnect: true,
    baseUrl: 'http://localhost:4200/',
    framework: 'jasmine',
    jasmineNodeOpts: {
        showColors: true,
        defaultTimeoutInterval: 30000,
        print: function() {}
    },
    useAllAngular2AppRoots: true,
    beforeLaunch: function() {
        require('ts-node').register({
            project: 'e2e'
        });
    },
    onPrepare: function() {
        jasmine.getEnv().addReporter(new SpecReporter());
    }
};

Bug description

Whenever I run my e2e tests, my browser opens and immediately closes. Protractor will then claim, that all tests have passed, which just can't be. I implemented a test like this to test this:

    it('should fail', () => {
        let ec = protractor.ExpectedConditions;
        let e = element(by.css('some-html-tag-which-definetly-doesnt-exist-in-my-app'));

        browser.wait(ec.presenceOf(e));
    });

Although this test should typically timeout, it will pass just fine in a split second.

If I add a spec like expect(true).toBe(false), the test will fail by the way.

I also had a beforeEach set up, with browser.ignoreSynchronization = true. After removing this line, all tests will pass like before, but protractor will fail anyway with this error:

/home/chris/workspace/mem-webclient/node_modules/protractor/built/exitCodes.js:87
if (e.message.indexOf(errMsg) !== -1) {                                                                                                         
              ^                                                                                                                                  

TypeError: Cannot read property 'indexOf' of undefined
    at Function.ErrorHandler.isError (/home/chris/workspace/mem-webclient/node_modules/protractor/built/exitCodes.js:87:30)
    at Function.ErrorHandler.parseError (/home/chris/workspace/mem-webclient/node_modules/protractor/built/exitCodes.js:98:26)
    at process.<anonymous> (/home/chris/workspace/mem-webclient/node_modules/protractor/built/launcher.js:169:54)
    at emitOne (events.js:96:13)
    at process.emit (events.js:188:7)
    at process.emit (/home/chris/workspace/mem-webclient/node_modules/ts-node/node_modules/source-map-support/source-map-support.js:419:21)
    at process.emit (/home/chris/workspace/mem-webclient/node_modules/protractor/node_modules/source-map-support/source-map-support.js:419:21)
    at process._fatalException (bootstrap_node.js:254:26)
/home/chris/workspace/my-webclient/node_modules/protractor/built/exitCodes.js:87
if (e.message.indexOf(errMsg) !== -1) {                                                                                                         
              ^                                                                                                                                  

TypeError: Cannot read property 'indexOf' of undefined
    at Function.ErrorHandler.isError (/home/chris/workspace/my-webclient/node_modules/protractor/built/exitCodes.js:87:30)
    at Function.ErrorHandler.parseError (/home/chris/workspace/my-webclient/node_modules/protractor/built/exitCodes.js:98:26)
    at process.<anonymous> (/home/chris/workspace/my-webclient/node_modules/protractor/built/launcher.js:169:54)
    at emitOne (events.js:96:13)
    at process.emit (events.js:188:7)
    at process.emit (/home/chris/workspace/my-webclient/node_modules/ts-node/node_modules/source-map-support/source-map-support.js:419:21)
    at process.emit (/home/chris/workspace/my-webclient/node_modules/protractor/node_modules/source-map-support/source-map-support.js:419:21)
    at process._fatalException (bootstrap_node.js:254:26)

(The error message above this sentence is copied from below referenced issue, since I currently can't access my own logs. I will insert my actual error message above this one as soon as I have time)

This also seems to be highly relevant, since it describes the very same behaviour: mgechev/angular-seed#1185
Sadly, this issue was closed without further investigation.

Since this issue seems to be quite rare, I assume that it is caused by some faulty dependency or so. Therefore I thought that maybe also my package.json file could help:

"dependencies": {
    "@angular/common": "2.0.0-rc.5",
    "@angular/compiler": "2.0.0-rc.5",
    "@angular/core": "2.0.0-rc.5",
    "@angular/forms": "0.3.0",
    "@angular/http": "2.0.0-rc.5",
    "@angular/platform-browser": "2.0.0-rc.5",
    "@angular/platform-browser-dynamic": "2.0.0-rc.5",
    "@angular/router": "3.0.0-rc.1",
    "@angular2-material/button": "2.0.0-alpha.7-4",
    "@angular2-material/card": "2.0.0-alpha.7-4",
    "@angular2-material/core": "2.0.0-alpha.7-4",
    "@angular2-material/grid-list": "2.0.0-alpha.7-4",
    "@angular2-material/list": "2.0.0-alpha.7-4",
    "@angular2-material/menu": "2.0.0-alpha.7-4",
    "@angular2-material/toolbar": "2.0.0-alpha.7-4",
    "angular2-moment": "1.0.0-beta.1",
    "core-js": "2.4.1",
    "moment": "2.14.1",
    "rxjs": "5.0.0-beta.11",
    "ts-helpers": "1.1.1",
    "zone.js": "0.6.12"
},
"devDependencies": {
    "@types/hammerjs": "2.0.32",
    "@types/jasmine": "2.2.33",
    "@types/protractor": "1.5.18",
    "angular-cli": "1.0.0-beta.11-webpack.8",
    "concurrently": "2.2.0",
    "codelyzer": "0.0.28",
    "jasmine-core": "2.5.0",
    "jasmine-spec-reporter": "2.7.0",
    "karma": "1.2.0",
    "karma-chrome-launcher": "2.0.0",
    "karma-jasmine": "1.0.2",
    "karma-remap-istanbul": "0.2.1",
    "protractor": "4.0.4",
    "ts-node": "1.3.0",
    "tslint": "3.15.1",
    "typescript": "2.0.0"
}

Reproduction

See #3505 (comment)

If you need more information, please let me know. I will try to get you everything you need to reproduce and hopefully eventually fix this

@cnishina
Copy link
Member

cnishina commented Aug 31, 2016

  • When you turn ignoreSynchronization to false true (updated: originally listed as false), ExpectedConditions will not work.
  • Having an unhelpful stacktrace because the error.message does not exist appears to not be correct. This should be investigated.

@ghost
Copy link
Author

ghost commented Aug 31, 2016

When you turn ignoreSynchronization to false, ExpectedConditions will not work.

It did work once with ignoreSynchronization = true. I think that false is the default. This did not work due to strange timeouts I could not fix in 3 days of work. I opened a StackOverflow question for this, but did not get any response so far.

Having an unhelpful stacktrace because the error.message does not exist appears to not be correct. This should be investigated.

While I agree with that statement, this is not the core problem. Like I wrote in the bug report, protractor will just pass all tests. By the way, this will also happen if I don't even have the application running. I can literally see that a browser window opens with the chrome error page - still the tests pass.

Please let me know what I can do for you to help your investigation

@ghost
Copy link
Author

ghost commented Aug 31, 2016

As promised, here is the actual error message I get

/home/chris/workspace/my-webclient/node_modules/protractor/built/exitCodes.js:87
if (e.message.indexOf(errMsg) !== -1) {                                                                                                         
              ^                                                                                                                                  

TypeError: Cannot read property 'indexOf' of undefined
    at Function.ErrorHandler.isError (/home/chris/workspace/my-webclient/node_modules/protractor/built/exitCodes.js:87:30)
    at Function.ErrorHandler.parseError (/home/chris/workspace/my-webclient/node_modules/protractor/built/exitCodes.js:98:26)
    at process.<anonymous> (/home/chris/workspace/my-webclient/node_modules/protractor/built/launcher.js:169:54)
    at emitOne (events.js:96:13)
    at process.emit (events.js:188:7)
    at process.emit (/home/chris/workspace/my-webclient/node_modules/ts-node/node_modules/source-map-support/source-map-support.js:419:21)
    at process.emit (/home/chris/workspace/my-webclient/node_modules/protractor/node_modules/source-map-support/source-map-support.js:419:21)
    at process._fatalException (bootstrap_node.js:254:26)

But I think that this is a rather small issue compared to blindly passing tests

@heathkit
Copy link
Contributor

Would it be possible for you to post a an example repository with the issue? I started with mgechev/angular2-seed and set it up to use ts-node in the protractor config the way you have it, but I'm still not able to reproduce the problem.

@ghost
Copy link
Author

ghost commented Aug 31, 2016

I will try. It's late now here, I will do so as soon as i wake up. By the way, I am not even using angular-seed. I am running on angular-cli

@ghost
Copy link
Author

ghost commented Sep 1, 2016

I found a quick way for you to reproduce this bug.

# terminal 1
# clone angular2-seed repo
$ git clone https://github.com/mgechev/angular2-seed.git
$ cd angular2-seed
# checkout the issue mentioned in mgechev/angular2-seed#1185 to be faulty
$ git checkout 9a8bf12eef0f28d310ecc0e568f6c5235422749e
# sidenote: At this point I opened package.json and changed 
# "dependencies.zone.js": "^0.6.12"
# to
# "dependencies.zone.js": "0.6.12"
# because 0.6.17 is buggy. Don't know if this changes anything
$ npm install
# once after install
$ npm run webdriver-update
# then anytime to reproduce
$ npm run webdriver-start
# terminal 2
$ npm run serve.e2e
# terminal 3
$ npm run e2e

npm run e2e will succeed immediately, and you will see the error with indexOf. You can now continue to further test this behaviour by doing this:

# terminal 2: Quit server using CTRL+C
$ ^C
# terminal 3:
$ npm run e2e

No webserver running, but tests will still pass. Now go to /src/client/app/app.component.e2e-spec.ts and apply this diff:

// Line 7
  it('should have a title', () => {
// Line 8 [---]
    expect(browser.getTitle()).toEqual('Welcome to angular2-seed!');
// Line 8 [+++]
    expect(browser.getTitle()).toEqual('surely not the correct title!');
// Line 9
  });
// ...

You will see that the tests will still pass, no matter whether you started the webserver or not. If you then do the following:

// Line 7
  it('should have a title', () => {
// Line 8 [---]
    expect(browser.getTitle()).toEqual('surely not the correct title!');
// Line 8 [+++]
    expect(true).toBe(false);
// Line 9
  });
// ...

The test will fail (assuming that you've started the webserver, otherwise it didn't recompile).

I hope this helps somehow. Please let me know if I can help any further or if you need anything.

@ghost
Copy link
Author

ghost commented Sep 1, 2016

Update: Same bevaiour on Debian 8.5, node 6.4.0 and npm 3.10.3

@heathkit
Copy link
Contributor

heathkit commented Sep 1, 2016

Thanks for the repro steps. I am able to reproduce this. I fixed the error handling, and this is the actual error:

[10:45:45] E/launcher - Error while waiting for Protractor to sync with the page: "window.getAllAngularTestabilities is not a function"
[10:45:45] E/launcher - Error
    at ElementArrayFinder.applyAction_ (/Users/heathkit/src/repro-3505/node_modules/protractor/built/element.js:395:27)
    at ElementArrayFinder._this.(anonymous function) [as getText] (/Users/heathkit/src/repro-3505/node_modules/protractor/built/element.js:97:30)
    at ElementFinder._this.(anonymous function) [as getText] (/Users/heathkit/src/repro-3505/node_modules/protractor/built/element.js:729:22)
    at Object.<anonymous> (app/+home/home.component.e2e-spec.ts:12:42)
    at /Users/heathkit/src/repro-3505/node_modules/jasminewd2/index.js:96:23
    at new Promise (/Users/heathkit/src/repro-3505/node_modules/selenium-webdriver/lib/promise.js:1043:7)
    at controlFlowExecute (/Users/heathkit/src/repro-3505/node_modules/jasminewd2/index.js:82:18)
    at TaskQueue.execute_ (/Users/heathkit/src/repro-3505/node_modules/selenium-webdriver/lib/promise.js:2790:14)
    at TaskQueue.executeNext_ (/Users/heathkit/src/repro-3505/node_modules/selenium-webdriver/lib/promise.js:2773:21)
    at /Users/heathkit/src/repro-3505/node_modules/selenium-webdriver/lib/promise.js:2697:25
[10:45:45] E/launcher - Process exited with error code 199

Also, it's worth noting that even though the tests are marked as passing (which is a bug), protractor exits with a non-zero exit code, indicating something went wrong. I'll try to figure out what's going on.

@heathkit heathkit self-assigned this Sep 1, 2016
@ghost
Copy link
Author

ghost commented Sep 1, 2016

That's strange, because if it would return a non-zero exit code, my CI tests wouldn't pass.

Update: I have tested what you said, and for me, it does return 0 as exit code. I have a script in my package.json called e2e, which is just an alias for protractor. If I run the following in the command line:

$ npm run e2e config/protractor.conf.js && echo "previous exit code was 0"

I get the following output:

Spec started
  app
    ✓ should load                                                                                                                                                     
    # ......                                                                                                                     
    ✓ this test should definetly fail                                                                                                                                                         

Executed 6 of 6 specs SUCCESS in 0.125 sec.                                                                                                                               
[19:53:34] I/launcher - 0 instance(s) of WebDriver still running                                                                                                          
[19:53:34] I/launcher - chrome #01 passed                                                                                                                                 
previous exit code was 0                       

I would also get the default npm error stuff if the script that was ran using a npm run command would return non-zero

@heathkit
Copy link
Contributor

heathkit commented Sep 1, 2016

It looks like this is related to the upgrade to selenium-webdriver 2.53.2, but it's a little hard to track down. If you have a minute, could you try installing protractor with 'npm install -g protractor' and launching your tests with that one?

@heathkit heathkit changed the title Tests pass immediately (but shouldn't) Protractor synchronization fails if multiple versions of selenium-webdriver are in node_modules Sep 1, 2016
@ghost
Copy link
Author

ghost commented Sep 1, 2016

I can try tomorrow. It's already late. I did not have this issues with angular-cli@1.0.0-beta.10. Only the upgrade to .11-webpack broke the e2e tests. I don't know much about the internals of ng-cli, so I can't tell whether it's related to selenium-webdriver or not.

@heathkit
Copy link
Contributor

heathkit commented Sep 1, 2016

Ok, I've tracked it down. The issue has to do with npm install non-determinism. That seed project depends on gulp-protractor ^2.4.0, which depends on protractor 3.3.0, which in turn depends on selenium-webdriver 2.52.0. It also has protractor ^4.0.0, which depends on selenium-webdriver 2.53.0. The simplest repo for this would be to start with any angular project, and do

npm install --save protractor@^4.0.0
npm install --save gulp-protractor@^2.4.0

You can use 'npm ls' to confirm that you have two versions of selenium-webdriver.

I'll keep working on this to make sure we don't fall over in this case (or at least throw a helpful error message). In the meantime, if you upgrade to gulp-protractor ^3.0.0 you should be fine.

@ghost
Copy link
Author

ghost commented Sep 1, 2016

Well, I am not even using gulp. I am using angular-cli. I just found that the guys at angular-seed faced the same issue and that was an easy way for me to show you how to reproduce this bug

@heathkit
Copy link
Contributor

heathkit commented Sep 1, 2016

The problem isn't gulp exactly, it's just that your package.json contains both "gulp-protractor": "^2.4.0", and "protractor": "^4.0.0",. If you change gulp-protractor to 3.0.0 (the version that depends on protractor 4), or even just remove it, you should be fine. You'll probably need to delete your node_modules directory and reinstall, though.

Basically, whatever the project, if you do npm ls and see two different versions of selenium-webdriver, upgrade things until there's only one version. Or remove stuff you don't need from pacakge.json.

@heathkit heathkit added this to the Upcoming milestone Sep 1, 2016
@ghost
Copy link
Author

ghost commented Sep 1, 2016

I just checked my npm ls output.
Turns out that angular-cli depends on protractor 3.3.0. Why is this issue so rare then? Because the newest angular-cli will create a package.json with protractor 4.0.4.
Every ng-cli user would be affected if he chooses to upgrade...

@heathkit
Copy link
Contributor

heathkit commented Sep 1, 2016

You may well be the first angular cli user to install Protractor 4.0.4 and file a bug on this. So thanks for that!

I sent angular-cli a PR to update, and we'll have a fix for this issue in the next Protractor release. In the meantime, you can install Protractor 4 globally and run your tests with the protractor command instead of the npm script. I might have a better workaround after a bit more investigation.

@ghost
Copy link
Author

ghost commented Sep 1, 2016

All right then! I will try it tomorrow :) Thank you so much for your quick and competent help. You are doing a great job!

@heathkit
Copy link
Contributor

heathkit commented Sep 1, 2016

Here's the smoking gun:

Trace: Webdriver 2.53.2 included.
    at Object.<anonymous> (/Users/heathkit/src/repro-3505/node_modules/protractor/node_modules/selenium-webdriver/index.js:25:9)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Module.require (module.js:367:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/heathkit/src/repro-3505/node_modules/protractor/built/element.js:7:17)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
[15:07:09] I/hosted - Using the selenium server at http://localhost:4444/wd/hub
[15:07:09] I/launcher - Running 1 instances of WebDriver
Trace: include webdriver 2.52.0
    at Object.<anonymous> (/Users/heathkit/src/repro-3505/node_modules/selenium-webdriver/index.js:25:9)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Module.require (module.js:367:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/heathkit/src/repro-3505/node_modules/jasminewd2/index.js:7:17)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
Spec started
Started

So jasminewd2 and protractor are using different instances of selenium webdriver. It turns out this was sort of known (see #2790 and angular/jasminewd #43). The fix is to make jasminewd take a webdriver instance from Protractor instead of doing require(), so we can guarantee they work with the same control flow. I'll be putting out a PR soon.

Also, it's interesting to note that this is a jasmine-specific issue - Mocha users aren't affected.

heathkit added a commit to heathkit/jasminewd that referenced this issue Sep 1, 2016
Fixex angular/protractor#3505, which was caused by Protractor and
Jasminewd finding different webdriver instances through require(), and
thus using different ControlFlows.
heathkit added a commit that referenced this issue Sep 1, 2016
heathkit added a commit to heathkit/protractor that referenced this issue Sep 1, 2016
heathkit added a commit to heathkit/protractor that referenced this issue Sep 1, 2016
@ghost
Copy link
Author

ghost commented Sep 2, 2016

I can confirm that this issue is related to selenium-webdriver. I deleted selenium-webdriver from /node_modules and symlinked /node_modules/protractor/node_modules/selenium-webdriver to /node_modules/selenium-webdriver, and everything worked as expected. Still I hope for a really fast fix, since I don't want to install protractor globally.

heathkit added a commit to heathkit/jasminewd that referenced this issue Sep 6, 2016
Fixex angular/protractor#3505, which was caused by Protractor and
Jasminewd finding different webdriver instances through require(), and
thus using different ControlFlows.
heathkit added a commit to heathkit/protractor that referenced this issue Sep 7, 2016
heathkit added a commit to heathkit/protractor that referenced this issue Sep 7, 2016
Fixes angular#3505 and angular#2790, which is caused by JasmineWd and Protractor using different
controlflow instances
heathkit added a commit that referenced this issue Sep 7, 2016
Fixes #3505 and #2790, which is caused by JasmineWd and Protractor using different
controlflow instances
@heathkit heathkit modified the milestones: 4.0.5, Upcoming Sep 7, 2016
@heathkit
Copy link
Contributor

heathkit commented Sep 7, 2016

4.0.5 is released and includes the fix for this.

@ghost
Copy link
Author

ghost commented Sep 7, 2016

Awesome, thank you so much! Will try tomorrow :)

[Edit] Just tried it, and it works. Thank you very much for that quick fix

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