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

Element explorer doesn't work on Node 8 #4307

Closed
monkpit opened this issue Jun 1, 2017 · 65 comments
Closed

Element explorer doesn't work on Node 8 #4307

monkpit opened this issue Jun 1, 2017 · 65 comments

Comments

@monkpit
Copy link
Contributor

@monkpit monkpit commented Jun 1, 2017

Bug report

  • Node Version: 8.0.0
  • Protractor Version: 5.1.2
  • Angular Version: n/a
  • Browser(s): Chrome / chromedriver 2.29.0
  • Operating System and Version Mac Sierra 10.12.5
  • Your protractor configuration file n/a

After installing node v8.0.0 and npm v5.0.0, reinstalling protractor globally and running webdriver-manager update, I cannot run protractor --elementExplorer because I receive the following error:

protractor --elementExplorer
(node:76684) [DEP0022] DeprecationWarning: os.tmpDir() is deprecated. Use os.tmpdir() instead.
[11:04:10] I/hosted - Using the selenium server at http://localhost:4444/wd/hub
[11:04:11] I/protractor -
[11:04:11] I/protractor - ------- Element Explorer -------
[11:04:11] I/protractor - Starting WebDriver debugger in a child process. Element Explorer is still beta, please report issues at github.com/angular/protractor
[11:04:11] I/protractor -
[11:04:11] I/protractor - Type <tab> to see a list of locator strategies.
[11:04:11] I/protractor - Use the `list` helper function to find elements by strategy:
[11:04:11] I/protractor -   e.g., list(by.binding('')) gets all bindings.
[11:04:11] I/protractor -
module.js:487
    throw err;
    ^

Error: Cannot find module '_debugger'
    at Function.Module._resolveFilename (module.js:485:15)
    at Function.Module._load (module.js:437:25)
    at Module.require (module.js:513:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/usr/local/lib/node_modules/protractor/built/debugger/debuggerCommons.js:1:82)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)

If I revert back to node 7.10.0 I don't get this error.

@NickTomlin
Copy link
Member

@NickTomlin NickTomlin commented Jun 1, 2017

I don't think we are currently testing against node 8 so it makes sense that this may be broken. Thanks for bringing this up!

@NickTomlin NickTomlin self-assigned this Jun 1, 2017
@NickTomlin
Copy link
Member

@NickTomlin NickTomlin commented Jun 1, 2017

I'll try to dig into this in the next few days but a PR to fix this would be very welcome!

@monkpit
Copy link
Contributor Author

@monkpit monkpit commented Jun 1, 2017

_debugger and the legacy CLI debugger were removed in Node 8: nodejs/node@90476ac

@GvS666
Copy link

@GvS666 GvS666 commented Jun 28, 2017

Any updates on this?

@bakasmarius
Copy link

@bakasmarius bakasmarius commented Jul 25, 2017

Could we please know what are the plans for Node 8 support? :)

@will-l-h
Copy link

@will-l-h will-l-h commented Aug 26, 2017

With Node v8 set to enter LTS in October, maybe we could get an update?

https://github.com/nodejs/LTS#lts-schedule1

@rodrigc
Copy link
Contributor

@rodrigc rodrigc commented Sep 6, 2017

According to https://nodejs.org/en/docs/guides/debugging-getting-started/#legacy-debugger ,
the node.js team is migrating users to the new inspect API.

@uriah-ascend
Copy link

@uriah-ascend uriah-ascend commented Oct 6, 2017

Are there plans from the team to get this working again with either the inspect API or something other approach?

@wzup
Copy link

@wzup wzup commented Oct 25, 2017

@phenomnomnominal
Copy link

@phenomnomnominal phenomnomnominal commented Nov 3, 2017

I've started having a look into this. Here are a bunch of guesses about how updating this might work:

As far as I can tell, the changes need to happen in debuggerCommons.js

Rather than require('_debugger'); it needs to use require('inspector'); (docs here). You can then open the inspector, create a session, connect to it, and then use session.post and the Chrome DevTools Protocol to send the messages to add the breakpoints.

I'll have a crack at a PR when I get some time.

@yxliang01
Copy link

@yxliang01 yxliang01 commented Nov 3, 2017

@phenomnomnominal Hey that's great! May I know when you are available for making the PR? Since this functionality is so useful, would be great if it can be created soon. It will speed up our development so much.
Thanks!

@qiyigg
Copy link
Contributor

@qiyigg qiyigg commented Nov 6, 2017

@phenomnomnominal Hi, we are planing to support node 8.0 recently, what's your current plan of fixing this issue?

@phenomnomnominal
Copy link

@phenomnomnominal phenomnomnominal commented Nov 6, 2017

Only what I outlined above. I was planning on having a crack at it this evening.

@qiyigg
Copy link
Contributor

@qiyigg qiyigg commented Nov 7, 2017

@phenomnomnominal that's great, thanks a lot!

@qiyigg
Copy link
Contributor

@qiyigg qiyigg commented Nov 12, 2017

@phenomnomnominal Hi, any updates so far?

@phenomnomnominal
Copy link

@phenomnomnominal phenomnomnominal commented Nov 12, 2017

I started having a go, but I was having issues with Selenium when trying to run the tests (any tips?). I’m going to have some more time Tuesday night. The new API is quite different, but I don’t foresee any real issues.

@qiyigg
Copy link
Contributor

@qiyigg qiyigg commented Nov 12, 2017

ok, thanks a lot. I am supposed to have some time after Monday, maybe I can also look into it after that.

@phenomnomnominal
Copy link

@phenomnomnominal phenomnomnominal commented Nov 14, 2017

I got... somewhere? Turns out debugging the debugger isn't as straightforward as I'd have hoped. @qiyigg did you have a chance to look at anything?

@qiyigg
Copy link
Contributor

@qiyigg qiyigg commented Nov 15, 2017

I will look into it today, thanks!

@phenomnomnominal
Copy link

@phenomnomnominal phenomnomnominal commented Nov 15, 2017

I’ll have some more time this evening too, we can compare notes later.

@Lilly2016
Copy link

@Lilly2016 Lilly2016 commented Nov 23, 2017

Hi, any progress on this issue in the last week? It's still occurring.

@ajklotz
Copy link

@ajklotz ajklotz commented May 2, 2018

This issue has been open for almost a year. Still no progress?

@mraible
Copy link

@mraible mraible commented May 2, 2018

@ajklotz I can confirm it still only works with Node 7. I've been using nvm to switch between Node versions in order to use element explorer. It's a pain, but it works!

@rodrigc
Copy link
Contributor

@rodrigc rodrigc commented May 2, 2018

@ajklotz @monkpit @mraible If you are able to run with Node 8 or higher, I recommend that you try to do the following:

  1. Watch this video "Protractor: A New Hope" https://youtu.be/6aPfHrSl0Qk?t=1051 , specifically starting around 17:31
  2. Switch to using Node 8 or higher
  3. Convert your tests to use the ES2017 async/await keywords: https://github.com/angular/protractor/blob/master/docs/async-await.md
  4. Add SELENIUM_PROMISE_MANAGER: false, to your protractor.conf.js
  5. Use the new debugger function and use chrome inspector to debug: https://github.com/angular/protractor/blob/master/docs/debugging.md#disabled-control-flow

I have done this with my own Protractor tests and confirm that it works.

@rodrigc
Copy link
Contributor

@rodrigc rodrigc commented May 2, 2018

@ajklotz @monkpit @mraible Here is an example where I converted Protractor tests to use async/await: https://github.com/buildbot/buildbot/pull/4074/files

Anything that returns a Promise, you stick an await in front of it such as:

  • .click()
  • .browser.wait()
  • .browser.get()
  • .getText()

If a function has a call to await, then the function signature must have async in front of it.

If you call a function with async, then you must await it.

It takes a while but once you do it, then it works.

@monkpit
Copy link
Contributor Author

@monkpit monkpit commented May 5, 2018

@rodrigc My tests area already using async/await, the point of this issue is that from the command line, protractor --elementExplorer doesn't work unless you use node 7.

@benjaminapetersen
Copy link

@benjaminapetersen benjaminapetersen commented May 7, 2018

FWIW, seems like a language feature like async/await should be irrelevant anyway. Perhaps a swap as a stop-gap fix makes sense, but Protractor doesn't imply dependence on that style.

@rodrigc
Copy link
Contributor

@rodrigc rodrigc commented May 7, 2018

@monkpit Yes you are absolutely right. The root cause of your problem is that on this line: https://github.com/angular/protractor/blob/master/lib/debugger/debuggerCommons.js#L1 , the _debugger module is imported, which is unavailable on node8. Anything that uses debuggerCommons.js will thus not work on node8, including elementExplorer.

So, if you want to use node8 or higher and debug with protractor, the key is to use async/await and follow the steps at: https://github.com/angular/protractor/blob/master/docs/debugging.md

The old debugging stuff won't work.

@monkpit
Copy link
Contributor Author

@monkpit monkpit commented May 7, 2018

Either it’s not going to get fixed (that’s fine, I can use the workaround) or it will be updated to use node 8+ (that’s also fine). But I would love to see an official response one way or the other.

@wswebcreation
Copy link
Collaborator

@wswebcreation wswebcreation commented May 8, 2018

@monkpit

I think the answer lies in this comment of @qiyigg.

For protractor debugger/explorer, we decided not to support it in node 8...

From what I've heard from @qiyigg when I talked to him the current focus in the team is lying on disabling control flow in Protractor tests.

I'm going to close this issue for now. It's still open for discussion.

@rodrigc
Copy link
Contributor

@rodrigc rodrigc commented May 8, 2018

@qiyigg I have started using the new debugger with chrome inspector, and node8 and it works well.

Can the protractor team start marking the documentation for the old debugging code which uses debuggerCommon.js as DEPRECATED? I agree with @monkpit that things are a bit confusing now where the code does not work with node8, but it is not marked as deprecated. Ultimately this old debugging code should just be deleted if it is never going to get fixed with node8.

@qiyigg
Copy link
Contributor

@qiyigg qiyigg commented May 8, 2018

If you take a look at the debugging document, we have already mentioned the debugger won't work on Node 8
https://github.com/angular/protractor/blob/master/docs/debugging.md#enabled-control-flow
"Note: Protractor debugger and element explorer cannot be used for Node.js 8+"

One thing to keep in mind is: not everyone is using Node 8+, we cannot say debugger is deprecated and enforce everyone to use async/await (Although we will do so inside google).

Apparently, moving to Node 8+ and async/await have many benefits and we should move to it eventually, but it is not an easy job since we have to change lots of our existing code. We are working on this inside google and try to accumulate more experience about migration (even migration tools)and hope it could also help users outside google eventually.

I think what we could do now is to make this error more clear, say, throw an exception: element explorer/debugger is not supported for Node 8+ instead of "Error: Cannot find module '_debugger'", A PR will be very welcomed.

@rodrigc
Copy link
Contributor

@rodrigc rodrigc commented May 8, 2018

@qiyigg I would suggest to make that warning in bold and ALL CAPS. It is a bit hard to catch on that page, because there are a lot of words.

@activedecay
Copy link

@activedecay activedecay commented Sep 21, 2018

i'm really happy with the new debugger because i can use intellij to run my tests. this is way better than the element explorer (which i rather liked) but using my IDE to debug tests is a huge win.

@woppa684
Copy link

@woppa684 woppa684 commented Oct 10, 2018

@qiyigg I work at a company that makes large production pinters. Because we changed all our UI's to use Angular (hurray!) we decided to use Protractor for the UI E2E tests (also hurray). Apart from these E2E tests we also have real end to end tests that work on an actual running system. All the test cases for that test system are specified in the Microsft TFS testing framework and we use a DSL to write them. This DSL loads the page objects we wrote for our UI's through an interactively started protractor (so the element explorer) and calls methods on them to execute its tests.

So far so good, you would say, we have thousands of these tests and they run really "as a user". What I make out of this conversation is that element explorer is dropped with the new node (and the new node is mandatory for upgrading Angular). This also means that all of a sudden our entire test base would stop working.

I get the change with async / wait and we will rewrite our page objects obviously to support it, but there's no real alternative to remotely insert protractor commands, right? I will always have to pass in "a test" that only calls "debugger", and then directly communicate with chrome to call a command on my page objects and then run to the next "debugger" call which I then probably will have to run in a while loop.

Were scenario's like these not supported? Won't they be? Or am I just missing something ... To me, debugging errors in your tests/code is entirely different from remotely instructing test commands. The latter is something element explorer used to facilitate :)

@woppa684
Copy link

@woppa684 woppa684 commented Oct 10, 2018

To at least share what my current solution is, I have written this test, which is the only system test I run with protractor (CompletableFuture is a helper class obviously):

jasmine.DEFAULT_TIMEOUT_INTERVAL = 3600000; // arbitrary large timeout
(global as any).systemTestsDone = new CompletablePromise<void>();

describe('TestHelper', () => {
  it('should provide a way to interactively run tests', async () => {
    await (global as any).systemTestsDone;
  });
});
node --inspect .\node_modules\protractor\bin\protractor .\systemTests\protractor.conf.js

This test then keeps running while I connect my (C#) WS client that acts as a bridge between the test specs, and the page objects. This bridge then instructs the browser to load the page objects and the tests start executing.

The last command I send to the browser is of course

global.systemTestsDone.complete()

so that the test completes normally. I don't think this is really awful, the only strange thing is that I now have to abuse a test to get into an interactive mode. If more people are missing functionality like this it might be a good idea to include it in protractor again. I don't mean an entire devtools protocol but the option to leave protractor running while you, for example, use the console of chrome or visual studio code as "element explorer".

@qiyigg
Copy link
Contributor

@qiyigg qiyigg commented Oct 10, 2018

add @vikerman, who will take over the Protractor stuff.

@woppa684
Copy link

@woppa684 woppa684 commented Oct 15, 2018

@vikerman Should I make a feature request out of the above comments?

In short, what I would like to have in protractor (since --elementExplorer is no longer working with recent node.js versions) is a mode that just starts protractor, ignores spec files and just keeps running until some manual method call (something like protractor.exit()?). We could start protractor in this mode with node --inspect, load some page objects and connect an external test runner to the debugger protocol and run the tests interactively.

@foofvalve
Copy link

@foofvalve foofvalve commented Nov 5, 2018

this would be really good if someone fixes this. I am currently using nvm as a work around.
i use nvm to install node 7.10.1 and fire up elementExplorer from there.
bit of lame workaround but it works for now

@gforceg
Copy link

@gforceg gforceg commented Nov 20, 2018

I downgraded to node v6 to get this to work and now I can't run my Angular 6 app because node 6 isn't supported in Angular 6+. It looks like Angular now targets node >= 8.9.0.

Is there a good work around that I can follow to get a protractor REPL w/o having to run two versions of node?

@yashwp
Copy link

@yashwp yashwp commented Dec 15, 2018

I'm having the same error in the console. I'm following these instructions given here
https://github.com/angular/protractor/blob/master/docs/debugging.md#enabled-control-flow

but still same error is coming 👎

@ernestoaparicio
Copy link

@ernestoaparicio ernestoaparicio commented Dec 24, 2018

So is this the end for browser.pause() / browser.debugger()? Appears we should be moving away from control flow and using node debugger.
https://github.com/angular/protractor/blob/master/docs/debugging.md

@ariskay
Copy link

@ariskay ariskay commented Jan 9, 2019

Using NVM to switch to node version 7.10.1 fixed the browser.pause() issue for me.

@suman90
Copy link

@suman90 suman90 commented Apr 24, 2019

I understand that async/await is the way forward, and using Webstorm to debug tests with breakpoints is absolutely seamless, but where I feel the absence of elementExplorer is its extended usage in the elementor package, which was a delightful way to interactively test out parts of code on the fly (in the omnibox) instead of running the entire test from scratch.
With the given debugging process for nodejs 8+, the commands from the console do not resolve promises while the inspector is paused at a breakpoint, which I realise is counter-intuitive, but all this has meant a subtle increase in time spent on writing/debugging tests, and loss of a widely used feature (going by number of responses on this thread).
Are there any plans to have a substitute for the old elementExplorer feature in protractor?

@vespertilian
Copy link

@vespertilian vespertilian commented May 1, 2019

@woppa684 Suggestion is working nicely for me. Thanks @woppa684. I just moved to node 10+ which has repl-await (so you can just await in the console)

Added all my config files for reference, hopefully it helps someone:

Special interactive debug spec - interactive.e2e.ts

import { LoginPage } from './src/pages/login.po';
import { AppPage } from './src/pages/app.po';
import { SwitchProfileSideSheet } from './src/side-sheets/switch-profile-side-sheet.po';
import { sel } from '../src/testing/get-component';

const login = new LoginPage();
const app = new AppPage();
const switchProfileSideSheet = new SwitchProfileSideSheet();

// add my own page objects to the global object so I can use them interactively.
global['sel'] = sel;
global['po'] = {
  login,
  app,
  switchProfileSideSheet,
};

(global as any).systemTestsDone = new Promise(function(_resolve, _reject) {
  global['finishInteractiveDebug'] = _resolve;
});

describe('TestHelper', () => {
  it('should provide a way to interactively run tests', async () => {
    await (global as any).systemTestsDone;
  });
});

package.json

    "e2e-interactive": "node --experimental-repl-await --inspect-brk ./node_modules/.bin/protractor ./e2e/protractor.interactive.conf",

protractor.interactive.conf.js

// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

// standard protractor config
const baseConfig = require('./protractor.conf');
const configCopy = Object.assign({}, baseConfig.config);

const oneDayInMilliSeconds = 1000 * 60 * 60 * 24;
// set timeout to a huge number
// so it's not an issue when we pause in the debugger
configCopy.allScriptsTimeout = oneDayInMilliSeconds;
configCopy.jasmineNodeOpts.defaultTimeoutInterval = oneDayInMilliSeconds;
// just load our interactive specs
configCopy.specs = ['./interactive.e2e.ts'];

console.log('interactive config', configCopy);
exports.config = configCopy;

@odikusar
Copy link

@odikusar odikusar commented Sep 18, 2019

I use browser.sleep(100000) instead of browser.pause()

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

Successfully merging a pull request may close this issue.

None yet