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

Failed: EPIPE write EPIPE with ElementArrayFinder.map and SELENIUM_PROMISE_MANAGER:false #4507

Open
wvanderdeijl opened this issue Sep 26, 2017 · 4 comments · May be fixed by #4508
Open

Failed: EPIPE write EPIPE with ElementArrayFinder.map and SELENIUM_PROMISE_MANAGER:false #4507

wvanderdeijl opened this issue Sep 26, 2017 · 4 comments · May be fixed by #4508

Comments

@wvanderdeijl
Copy link

We have intermittent errors Error: EPIPE write EPIPE when using the map function of ElementArrayFinder when SELENIUM_PROMISE_MANAGER is set to false. I have the feeling this is caused by the multiple (async) map callbacks being run in parallel which freaks webdriver out. With SELENIUM_PROMISE_MANAGER set to false the Promise.all construction in ElementArrayFinder.map will run the commands concurrently.

Having SELENIUM_PROMISE_MANAGER to true ensures all map functions are executed one at a time as each command waits for the previous promise to resolve.

You can see a test case at wvanderdeijl/protractor-mcve@24aa9de

The exception we get is:

    Error: EPIPE write EPIPE
        at ClientRequest.<anonymous> (/Users/wilfred/git/protractor-mcve/node_modules/selenium-webdriver/http/index.js:238:15)
        at emitOne (events.js:115:13)
        at ClientRequest.emit (events.js:210:7)
        at Socket.socketErrorListener (_http_client.js:401:9)
        at emitOne (events.js:115:13)
        at Socket.emit (events.js:210:7)
        at onwriteError (_stream_writable.js:406:12)
        at onwrite (_stream_writable.js:428:5)
        at _destroy (internal/streams/destroy.js:39:7)
        at Socket._destroy (net.js:552:3)Error
        at ElementArrayFinder.applyAction_ (/Users/wilfred/git/protractor-mcve/node_modules/protractor/lib/element.ts:482:23)
        at ElementArrayFinder.(anonymous function).args [as getText] (/Users/wilfred/git/protractor-mcve/node_modules/protractor/lib/element.ts:96:21)
        at ElementFinder.(anonymous function).args [as getText] (/Users/wilfred/git/protractor-mcve/node_modules/protractor/lib/element.ts:873:14)
        at element.all.map.elem (/Users/wilfred/git/protractor-mcve/example_spec.js:4:73)
        at arr.map (/Users/wilfred/git/protractor-mcve/node_modules/protractor/lib/element.ts:657:25)
        at Array.map (<anonymous>)
        at asElementFinders_.then (/Users/wilfred/git/protractor-mcve/node_modules/protractor/lib/element.ts:656:22)
        at <anonymous>
        at process._tickCallback (internal/process/next_tick.js:188:7)

Not sure if the issue is OS or browser dependent. We use MacOS 10.13 (High Sierra), Chrome 61.0.3163.100 (both headless and normal), Node 8.4.0, Protractor 5.1.2

@wvanderdeijl
Copy link
Author

Might be related to #4294 but I decided to log a separate issue as this is clearly related to the Promise.all in ElementArrayFinder.map and #4294 seems to be a different situation. However, #4294 might also be caused by some part in protractor where concurrent webdriver commands are submitted

@wvanderdeijl wvanderdeijl linked a pull request Sep 26, 2017 that will close this issue
@angelfraga
Copy link

angelfraga commented Sep 29, 2017

I have got the same issues on my e2e tests.
Around of 60% times there are 'EPIPE write EPIPE' errors when there a complex functionality that involves ElementArrayFinder.

Ex:

myElement.cc.ts

   constructor(private mainEl: ElementFinder = $('.SectionsContainer')) {}
    ...
    async getTextFromSubSections(): Promise<string[]> { 
        let sectionElList = this.mainEl.$$('.Sections');
        let  groupText = await Promise.all(sectionElList.map<Promise[string]>( element => {
             return element.getText();
        }));
        return groupText;
     } 
   ...

myElement.spec.ts

   import * as _ from 'lodash';
   ...
    const toBeSectionTexts = [...];
    ...
    const expectedSectionTexts = await getTextFromSubSections();
    expectedSectionTexts.forEach( (text)  =>{
        expect(_.includes(toBeSectionTexts, text)).toBe(true)
    });
   ...

I m going to fork your repository 'protractor-mcve' to add a debuggable example 👍

wvanderdeijl added a commit to wvanderdeijl/protractor that referenced this issue Oct 4, 2017
@wvanderdeijl
Copy link
Author

wvanderdeijl commented Oct 4, 2017

@angelfraga Problem is causes by your Promise.all which executes the getText() for all the elements in parallel. Webdriver doesn't seem to like concurrent requests (at least not with ChromeDriver on MacOS).
The trick would be not to use Promise.all but chain all the promises to ensure sequential execution. Or use this.mainEl.$$('.Sections').map. The map function on ElementArrayFinder will take care of the promise chaining once PR #4508 has been merged. The current implementation also uses a Promise.all and suffers from this issue

@angelfraga
Copy link

angelfraga commented Oct 5, 2017

Thanks 😃 , but also i have tried different ways to implement it, in spite of this any without success, the mostly ways got errors. Another two examples more:

...
    let  groupText: string[] = await  sectionElList.map<string>( element => {
        return element.getText();
     });
...

...
    let  elements: ElementFinder[] = await  sectionElList;
    let groupText: string[] = [];

    for(let i =0; i < elements.length; i++) {
          groupText.push(await elements[i].getText());
    }
...

Also i work with MacOS Sierra. For example in CI(JENKINS) there is not EPIPE errors.
About local (MacOS Sierra) , i would like to say that i checked my test as success after forcing the browser reload between each test.

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

Successfully merging a pull request may close this issue.

2 participants