BackstopJS icon indicating copy to clipboard operation
BackstopJS copied to clipboard

BackstopJS test execution failing: "Error: Stream not writable"

Open radicalbender opened this issue 9 years ago • 28 comments

So I've just started tinkering with BackstopJS. I setup some basic tests and was trying to work it into my normal build process in gulp.

For some reason though, the script just stopped executing correctly. The test worked fine several times earlier today, I came back later, made some CSS changes in my project, ran another test, and received this error:

Bitmap file generation completed.
COMMAND | Executing core for `report`
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: Stream not writable
    at ChunkStream.write (/Users/*****/Sites/*****/node_modules/pngjs/lib/chunkstream.js:46:24)
    at PNG.write (/Users/*****/Sites/*****/node_modules/pngjs/lib/png.js:92:16)
    at ReadStream.ondata (_stream_readable.js:525:20)
    at emitOne (events.js:77:13)
    at ReadStream.emit (events.js:169:7)
    at readableAddChunk (_stream_readable.js:146:16)
    at ReadStream.Readable.push (_stream_readable.js:110:10)
    at onread (fs.js:1738:12)
    at FSReqWrap.wrapper [as oncomplete] (fs.js:576:17)

For comparison, here is the same output from earlier today:

Bitmap file generation completed.
COMMAND | Executing core for `report`
compare | ERROR { size: isDifferent, content: 40.95%, threshold: 0.1% }: ***** *****_0_document_0_phone.png
   See: /Users/*****/Sites/*****/backstop_data/bitmaps_test/20161115-135709/failed_diff_*****_0_document_0_phone.png
compare | OK: ***** *****_0_document_0_phone.png
compare | OK: ***** *****_0_document_0_phone.png
compare | ERROR { size: ok, content: 1.06%, threshold: 0.1% }: ***** *****_0_document_1_tablet_v.png
   See: /Users/*****/Sites/*****/backstop_data/bitmaps_test/20161115-135709/failed_diff_*****_0_document_1_tablet_v.png
compare | OK: ***** *****_0_document_1_tablet_v.png
compare | OK: ***** *****_0_document_1_tablet_v.png
compare | ERROR { size: ok, content: 0.60%, threshold: 0.1% }: ***** *****_0_document_2_tablet_h.png
   See: /Users/*****/Sites/*****/backstop_data/bitmaps_test/20161115-135709/failed_diff_*****_0_document_2_tablet_h.png
compare | OK: ***** *****_0_document_2_tablet_h.png
compare | OK: ***** *****_0_document_2_tablet_h.png
 report |
          Test completed...
 report | 6 Passed
 report | 3 Failed

I tried deleting the html_report directory and rerunning the script. That didn't work. I tried deleting bitmaps_reference and bitmaps_test. It could recreate the images, but the test failed in the same fashion.

There's also nothing fancy about the backstop.json file. I think it's just adapted from one of the demos:

{
  "id": "*****",
  "viewports": [
    {
      "name": "phone",
      "width": 320,
      "height": 480
    },
    {
      "name": "tablet_v",
      "width": 568,
      "height": 1024
    },
    {
      "name": "tablet_h",
      "width": 1024,
      "height": 768
    }
  ],
  "scenarios": [
    {
      "label": "*****",
      "url": "*****/*****/index.html",
      "readyEvent": "backstopjs_ready",
      "misMatchThreshold" : 0.1,
      "onBeforeScript": "onBefore.js",
      "onReadyScript": "onReady.js"
    },
    {
      "label": "*****",
      "url": "*****/*****/index.html",
      "readyEvent": "backstopjs_ready",
      "misMatchThreshold" : 0.1,
      "onBeforeScript": "onBefore.js",
      "onReadyScript": "onReady.js"
    },
    {
      "label": "*****",
      "url": "*****/*****/index.html",
      "readyEvent": "backstopjs_ready",
      "misMatchThreshold" : 0.1,
      "onBeforeScript": "onBefore.js",
      "onReadyScript": "onReady.js"
    }
  ],
  "paths": {
    "bitmaps_reference": "backstop_data/bitmaps_reference",
    "bitmaps_test": "backstop_data/bitmaps_test",
    "casper_scripts": "backstop_data/casper_scripts",
    "html_report": "backstop_data/html_report",
    "ci_report": "backstop_data/ci_report"
  },
  "casperFlags": [],
  "engine": "phantomjs",
  "report": ["browser"],
  "debug": false
}

Does anyone have any ideas?

radicalbender avatar Nov 15 '16 22:11 radicalbender

The error is coming from the pngjs package. Looks like it cant write to the destination.

Stupid question -- You don't literally use * in your filenames right? You're just redacting manually for demo purposes -- correct?

Does this fix itself if you blow away the backstopjs directory and start over?

garris avatar Nov 15 '16 22:11 garris

Yes, the *** is meant to anonymize the client that I'm working on. :)

I deleted the backstop_data directory. I also tried removing it from package.json, running npm prune and then installing everything from scratch, and I'm still getting the exact same error.

I also tried chmod 777 backstop_data just to see if that was the problem. Still nothing.

radicalbender avatar Nov 15 '16 22:11 radicalbender

Please include your full terminal log.

garris avatar Nov 15 '16 23:11 garris

Here's what I am getting (I'm leaving out the full source code because it's extensive):

CasperJS: </body>
CasperJS: [info] [phantom] Step anonymous 88/90: done in 5640ms.
CasperJS:  [info] [phantom] Step anonymous 89/90: done in 5658ms.
CasperJS:  Capturing screenshots for tablet_h (1024x768)
CasperJS:  [debug] [phantom] Capturing page to /Users/*****/Sites/*****/backstop_data/bitmaps_test/20161128-140232/*****_0_document_2_tablet_h.png
CasperJS:  [info] [phantom] Capture saved to /Users/*****/Sites/*****/backstop_data/bitmaps_test/20161128-140232/*****_0_document_2_tablet_h.png
CasperJS:  [info] [phantom] Step anonymous 90/90: done in 5856ms.
CasperJS: [info] [phantom] Done 90 steps in 5857ms
CasperJS:  Comparison config file updated.
CasperJS:  [debug] [phantom] Navigation requested: url=about:blank, type=Other, willNavigate=true, isMainFrame=true
CasperJS:  [debug] [phantom] url changed to "about:blank"

Bitmap file generation completed.
COMMAND | Executing core for `report`
events.js:141
      throw er; // Unhandled 'error' event
      ^

Error: Stream not writable
    at ChunkStream.write (/Users/*****/Sites/*****/node_modules/pngjs/lib/chunkstream.js:46:24)
    at PNG.write (/Users/*****/Sites/*****/node_modules/pngjs/lib/png.js:92:16)
    at ReadStream.ondata (_stream_readable.js:525:20)
    at emitOne (events.js:77:13)
    at ReadStream.emit (events.js:169:7)
    at readableAddChunk (_stream_readable.js:146:16)
    at ReadStream.Readable.push (_stream_readable.js:110:10)
    at onread (fs.js:1738:12)
    at FSReqWrap.wrapper [as oncomplete] (fs.js:576:17)

radicalbender avatar Nov 28 '16 20:11 radicalbender

Same here

      COMMAND | Executing core for `report`
Uncaught exception: Stream not writable Error: Stream not writable
    at ChunkStream.write (/usr/local/lib/node_modules/backstopjs/node_modules/node-resemble-js/node_modules/pngjs/lib/chunkstream.js:46:24)
    at PNG.write (/usr/local/lib/node_modules/backstopjs/node_modules/node-resemble-js/node_modules/pngjs/lib/png.js:92:16)
    at ReadStream.ondata (_stream_readable.js:555:20)
    at emitOne (events.js:96:13)
    at ReadStream.emit (events.js:188:7)
    at readableAddChunk (_stream_readable.js:176:18)
    at ReadStream.Readable.push (_stream_readable.js:134:10)
    at onread (fs.js:2004:12)
    at FSReqWrap.wrapper [as oncomplete] (fs.js:681:17)
/usr/local/lib/node_modules/backstopjs/cli/index.js:57
    throw err;
    ^

Error: Stream not writable
    at ChunkStream.write (/usr/local/lib/node_modules/backstopjs/node_modules/node-resemble-js/node_modules/pngjs/lib/chunkstream.js:46:24)
    at PNG.write (/usr/local/lib/node_modules/backstopjs/node_modules/node-resemble-js/node_modules/pngjs/lib/png.js:92:16)
    at ReadStream.ondata (_stream_readable.js:555:20)
    at emitOne (events.js:96:13)
    at ReadStream.emit (events.js:188:7)
    at readableAddChunk (_stream_readable.js:176:18)
    at ReadStream.Readable.push (_stream_readable.js:134:10)
    at onread (fs.js:2004:12)
    at FSReqWrap.wrapper [as oncomplete] (fs.js:681:17)

verpixelt avatar Sep 11 '17 19:09 verpixelt

Same here on Node v8.9.3 and Backstop v3.0.37

events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: Stream not writable
    at module.exports.ChunkStream.write (/Users/xxx/node_modules/node-resemble-js/node_modules/pngjs/lib/chunkstream.js:46:24)
    at exports.PNG.PNG.write (/Users/xxx/node_modules/node-resemble-js/node_modules/pngjs/lib/png.js:92:16)
    at ReadStream.ondata (_stream_readable.js:639:20)
    at emitOne (events.js:116:13)
    at ReadStream.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at ReadStream.Readable.push (_stream_readable.js:208:10)
    at onread (fs.js:2050:12)
    at FSReqWrap.wrapper [as oncomplete] (fs.js:658:17)

web-bert avatar Jan 08 '18 15:01 web-bert

Same here. Any update on this?

Node v9.6.1 backstop v3.1.19

compare | OK: About jcsi_test_About_0_document_2_tablet_h.png
events.js:112
      throw er; // Unhandled 'error' event
      ^

Error: Stream not writable
    at module.exports.ChunkStream.write (/Users/dellabaines/.nvm/versions/node/v9.6.1/lib/node_modules/backstopjs/node_modules/node-resemble-js/node_modules/pngjs/lib/chunkstream.js:46:24)
    at exports.PNG.PNG.write (/Users/dellabaines/.nvm/versions/node/v9.6.1/lib/node_modules/backstopjs/node_modules/node-resemble-js/node_modules/pngjs/lib/png.js:92:16)
    at ReadStream.ondata (_stream_readable.js:646:20)
    at ReadStream.emit (events.js:127:13)
    at addChunk (_stream_readable.js:269:12)
    at readableAddChunk (_stream_readable.js:256:11)
    at ReadStream.Readable.push (_stream_readable.js:213:10)
    at fs.read (fs.js:2123:12)
    at FSReqWrap.wrapper [as oncomplete] (fs.js:680:17)
      compare | OK: News jcsi_test_News_0_document_0_phone.png

dellabravo avatar Feb 27 '18 19:02 dellabravo

Can you try running the sanity check? https://github.com/garris/BackstopJS#sanity-test-does-backstop-work-in-my-enviornment

garris avatar Feb 27 '18 20:02 garris

Yeah, sanity check worked and after running it I'm no longer seeing the 'Stream not writable error' when running from my project.

Thanks!

dellabravo avatar Feb 27 '18 21:02 dellabravo

I'm getting the same error even though sanity check does work correctly.

I tried debugging it and the last place where code executes correctly is the compare-resemble.js file, up to the line with comparison.onComplete. Callback passed to this method never executes, because of "Stream not writable" happening inside of node-resemble-js.

So, this seems to be a bug in node-resemble-js or even deeper. One thing that might be done on the backstopjs side is to catch such error and handle it somehow. Current behavior is very annoying, because backstop hangs forever during the "report" phase.

Unfortunately, node-resemble-js has no onError method so the only place where backstopjs can recognize that something went wrong, is in core/util/compare/index.js file, in compareImages method. The following code properly rejects a promise if the child comparison process ended with error (ie. because of uncaught "Stream not writable").

worker.on('exit', function (code, signal) {
  if (code > 0) {
    logger.error('EXECUTION ERROR');
    reject('There was an error in child process');
  }
});

However, I didn't check what impact this rejection will have on the rest of the code. Good thing is that it doesn't hang with this lines added.

aczekajski avatar Jun 27 '19 10:06 aczekajski

I've traced the error down to the pngjs package that lies below node-resemble-js.

First problem is that node-resemble-js currently uses pngjs@~2.2.0 while 3.4.0 is available. However, this does not fix the issue, only the error thrown changes to Unexpected end of input. Luckily, there is a fix for that ready but waiting for author to merge it into pngjs: https://github.com/lukeapage/pngjs/pull/130

When it gets merged, the dependency of node-resemble-js needs to be changed or maybe npm-shrinkwrap might be used in BackstopJs to enforce newer pngjs.

aczekajski avatar Jun 27 '19 16:06 aczekajski

Still getting the same error. Any news on this? Is there some workaround for this problem? Or is there some reason already known why it is occuring?

schrufygroovy avatar Dec 06 '19 09:12 schrufygroovy

Aforementioned bug in pngjs is still there, still not merged. I've also tried to make contact with author of node-resemble-js to take care of this unmaintained library but there was no answer from the author.

aczekajski avatar Dec 06 '19 16:12 aczekajski

https://github.com/lukeapage/pngjs/pull/130 got merged. Unfortunately node-resemble-js remains dead. Efforts to reach its author rendered futile. Any other efforts to merge different versions of resemble forks too. How about taking over the library in te form of own fork?

aczekajski avatar Apr 09 '20 16:04 aczekajski

There seems to be a runtime environment relation to this issue. After updating NodeJs version 8.x -> 12.x this problem disappeared.

wojtus avatar May 05 '20 15:05 wojtus

here seems to be a runtime environment relation to this issue. After updating NodeJs version 8.x -> 12.x this problem disappeared.

Unfortunately did not disappear completly :( With Node 8.x only ~10% executions succeeded. With Node 12.x ~10% executions fail.

wojtus avatar May 06 '20 05:05 wojtus

same here. It happened for me consistently in a specific scenario. My workaround was forcing node-resemble dependency of pngjs to 4.0.1 by changing in my package-lock.json from :

"node-resemble-js": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/node-resemble-js/-/node-resemble-js-0.2.0.tgz",
      "integrity": "sha1-ijbGZ4ph5dhFX+xYAJsbAnGxkJo=",
      "requires": {
        "jpeg-js": "0.2.0",
        "pngjs": "~2.2.0"
      },
      "dependencies": {
        "pngjs": {
          "version": "2.2.0",
          "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-2.2.0.tgz",
          "integrity": "sha1-ZJZjYJoOurh8jwiz/nJASLUdnX8="
        }
      }
    },

to:


  "node-resemble-js": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/node-resemble-js/-/node-resemble-js-0.2.0.tgz",
      "integrity": "sha1-ijbGZ4ph5dhFX+xYAJsbAnGxkJo=",
      "requires": {
        "jpeg-js": "0.2.0"
      },
      "dependencies": {
        "pngjs": {
          "version": "4.0.1"
       }
     }
 },
....

For this new dependency to work, node_modules must be empty, then run npm install and from then on use only npm ci

nadavpa avatar Jun 30 '20 13:06 nadavpa

Also running suddenly into this error with our 200+ images after it was working well for a long time.

It seem that current BS master is using "node-resemble-js": "^0.2.0" which might include a problem, but certainly is outdated.

I added an issue https://github.com/lksv/node-resemble.js/issues/49 to clear things up, but as far as I read above this one is dead.

@garris Maybe there is an option to upgrade to one of the following?

  • https://www.npmjs.com/package/node-resemble-v2
  • https://www.npmjs.com/package/resemblejs-node
  • https://www.npmjs.com/package/resemblejs-papandreou
  • https://www.npmjs.com/package/resemblejs (the original without "node")

digitaldonkey avatar Mar 31 '21 10:03 digitaldonkey

Hello Folks! Hi @garris,

https://github.com/lksv/node-resemble.js/ maintainer here! Long time no see. Sorry for such late response, last year I've merged a pull request with some version updates but didn't published a new version with tags.

So I've published a new version v1.2.0 on github but I don't think I've access to npm package. What I can suggest is pointing to master instead of old versions and kindly let me know if that helps!

mirzazeyrek avatar May 03 '21 18:05 mirzazeyrek

@mirzazeyrek I really prefer to pull in a released version as opposed to reference a tagged version. Does @lksv have access to publish a release?

@digitaldonkey This is regarding https://github.com/lksv/node-resemble.js/issues/49 that you logged.

benbcai avatar May 03 '21 23:05 benbcai

Hi @mirzazeyrek -- Good to hear from you -- hoping you and your family are in good health!

Are you saying that you made a fix but you can't access the NPM repo? Do you want to simply start your own NPM release fork and have BackstopJS point to that?

@benbcai would this approach resolve your issue?

garris avatar May 04 '21 00:05 garris

Hi @garris, I think what @mirzazeyrek is saying is that node-resemble-js v1.2.0 is only tagged in github but it is not published to npm. As you can see here in npmjs, the latest released version is 0.2.0. BackstopJS currently depends on node-resemble-js v0.2.0, which then depends on pngjs v2.2.0. The Stream not writable error reported here is fixed in a newer version of pngjs. node-resemble-js tagged version 1.2.0 is updated to depend on pngjs v6.0.0 which has the fix but node-resemble-js v1.2.0 is not released and we can't use it.

The issue I'm having is actually in terra-toolkit which currently is using node-resemble-js v1.2.0. What I'm requesting is if we can get a released version of resemble-js v1.2.0 so it can use pngjs v6.0.0 instead of referencing the master branch I don't want to do in production code.

benbcai avatar May 04 '21 04:05 benbcai

@benbcai thank you for explaining. Please let me know if you can get this sorted out. I am happy to bump BackstopJS when the package version is published to npm.

garris avatar May 04 '21 04:05 garris

Sadly I didn't get a response from Lukas and I have published a new version on npm:

https://www.npmjs.com/package/@mirzazeyrek/node-resemble-js

Please let me know if this published version works for you ? @benbcai @digitaldonkey @garris

mirzazeyrek avatar May 04 '21 23:05 mirzazeyrek

Great! Will do this soon -- thank you @mirzazeyrek.

garris avatar May 05 '21 05:05 garris

Thank you @mirzazeyrek for publishing a new release!

benbcai avatar May 05 '21 20:05 benbcai

Hi @garris when would you be able to bump the version / test the fix?

GuusHamm avatar May 18 '21 07:05 GuusHamm

I have also started getting bitten by this. Is there a known workaround until there's a new release of backstop?

(I tried using npm-force-resolutions, but it doesn't seem to take, probably because the fixed node-resemble-js is actually a new package published under @mirzazeyrek's namespace, rather than just a newer version.)

SeanMcMillan avatar Jun 06 '21 14:06 SeanMcMillan