laurentj / slimerjs

A scriptable browser like PhantomJS, based on Firefox
http://slimerjs.org
Other
3k stars 259 forks source link

Slimer 0.10.0 issues with system.stdout Stream #478

Open eolalde opened 8 years ago

eolalde commented 8 years ago

versions

So I recently upgraded from 0.9.6 to 0.10.0 to get advantage of the new system.stdin and system.stdout features in my script. But now, stdout stream is not working and throws an Error saying "/dev/stdout" path doesn't exist, but it definitely does exist. The code lines are as follows:

var page = require('webpage').create(),`
    system = require('system');
require.globals.page = page;

phantom.onError = function (msg, trace) {
    var msgStack = ['BROWSER ERROR: ' + msg];
    if (trace && trace.length) {
        msgStack.push('TRACE:');
        trace.forEach(function(t) {
            msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function +')' : ''));
        });
    }
    console.log(msgStack.join('\n'));
    slimer.exit(1);
};
page.onError = function (msg, trace) {
    var msgStack = ['PAGE ERROR: ' + msg];
    if (trace && trace.length) {
        msgStack.push('TRACE:');
        trace.forEach(function(t) {
            msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function +')' : ''));
        });
    }
    console.log(msgStack.join('\n'));
    slimer.exit(1);
};
system.stdout.write('asd');`

Actual results:

I keep getting this Error:

BROWSER ERROR: path does not exist: /dev/stdout
TRACE:
 -> resource://slimerjs/addon-sdk/sdk/io/file.js: 80
 -> resource://slimerjs/addon-sdk/sdk/io/file.js: 80 (in function friendlyError)
 -> resource://slimerjs/addon-sdk/sdk/io/file.js: 357 (in function open)
 -> resource://slimerjs/slimer-sdk/system.js: 216 (in function getOutput)
 -> resource://slimerjs/slimer-sdk/system.js: 261 (in function .get)
 -> file:///PATH/TO/slimerScripts/main.js: 31

Could someone please help with this? I was so excited with the new stdin and stderr Streams implementation, but the result was that now stdout doesn't work. I'm spawning slimerjs as a child_process of a Node.js process.

MarkR42 commented 8 years ago

Can you write a small script to reproduce the issue, outside of your nodejs environment?

Is it possible that it's running inside some kind of chroot or container?

Mark

On 10 May 2016 at 20:26, eolalde notifications@github.com wrote:

versions

  • SlimerJS: 0.10.0
  • Firefox: 46.0
  • Operating system: Ubuntu 14.04

Steps to reproduce the issue

So I recently upgraded from 0.9.6 to 0.10.0 to get advantage of the new system.stdin and system.stdout features in my script. But now, stdout stream is not working and throws an Error saying "/dev/stdout" path doesn't exist, but it definitely does exist. The code lines are as follows:

`var page = require('webpage').create(), system = require('system'); require.globals.page = page;

phantom.onError = function (msg, trace) { var msgStack = ['BROWSER ERROR: ' + msg]; if (trace && trace.length) { msgStack.push('TRACE:'); trace.forEach(function(t) { msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function +')' : '')); }); } console.log(msgStack.join('\n')); slimer.exit(1); }; page.onError = function (msg, trace) { var msgStack = ['PAGE ERROR: ' + msg]; if (trace && trace.length) { msgStack.push('TRACE:'); trace.forEach(function(t) { msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function +')' : '')); }); } console.log(msgStack.join('\n')); slimer.exit(1); }; system.stdout.write('asd');` Actual results:

I keep getting this Error: BROWSER ERROR: path does not exist: /dev/stdout TRACE: -> resource://slimerjs/addon-sdk/sdk/io/file.js: 80 -> resource://slimerjs/addon-sdk/sdk/io/file.js: 80 (in function friendlyError) -> resource://slimerjs/addon-sdk/sdk/io/file.js: 357 (in function open) -> resource://slimerjs/slimer-sdk/system.js: 216 (in function getOutput) -> resource://slimerjs/slimer-sdk/system.js: 261 (in function .get) -> file:///home/eusebioolalde/work/workLocal/header-watch.git/lib/browserDriver/slimerScripts/main.js: 31

Could someone please help with this? I was so excited with the new stdin and stderr Streams implementation, but the result was that now stdout doesn't work. I'm spawning slimerjs as a child_process of a Node.js process.

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/laurentj/slimerjs/issues/478

eolalde commented 8 years ago

Can you write a small script to reproduce the issue, outside of your nodejs environment?

Is it possible that it's running inside some kind of chroot or container?

Mark

I ran the same script directly from bash command line and the stdout stream was piped directly to the cmd output, and the 'asd' string was logged instantly with no errors. It is possible that node runs the child process in some kind of sandboxed environment, but what I can't understand is why 0.9.6 was successfully writing to /dev/stdout in the same environment.

If it is a problem with the environment in which node launches slimer as a child process, could you give any suggestions on how to approach this? Do you think there's a workaround to get SlimerJS process to communicate with Node.js process?

Thanks a lot for following up, really appreciate it

Eusebio

eolalde commented 8 years ago

@MarkR42 I've continued the investigation, something that strangely worked, was using the same Streams, i.e. inheriting Node's stdio streams, only that now I've found myself sending data from the parent process to both the child process and itself. I'll keep looking into it, but if the new finding sparks any idea, please share :)

Eusebio

laurentj commented 8 years ago

Probably that standard input/output of a child process of Node are not /dev/stdout /dev/stdin, but other file descriptors (some pipe or something like that?). So probably I should not use /dev/stdout, /dev/stdin for system.sdtout/system.stdin, but i should open file descriptor 1 and 2, like in C. But I don't know yet how to do with the Mozilla API. (I don't remember if file descriptor 1 is always /dev/stdout)

In 0.9.6, system.stdout worked because it used the dump() javascript function, which certainly use the file descriptor 1, and not /dev/stdout directly.

MarkR42 commented 8 years ago

Maybe node closed fd0,1 or 2?

Really having fd0,1,2 closed is a very bad situation, because then when you open another random file, it can become stdin / stdout.

If nodejs doesn't want the child to access its stdin/stdout, it should make them go to /dev/null instead.

Under Linux, /dev/stdout is usually a symlink to /proc/self/fd/1, so I suppose if /proc isn't mounted (or isn't visible) in the child process, that will give this error.

Mark

On 11 May 2016 at 11:11, Laurent Jouanneau notifications@github.com wrote:

Probably that standard input/output of a child process of Node are not /dev/stdout /dev/stdin, but other file descriptors (some pipe or something like that?). So probably I should not use /dev/stdout, /dev/stdin for system.sdtout/system.stdin, but i should open file descriptor 1 and 2, like in C. But I don't know yet how to do with the Mozilla API.

In 0.9.6, system.stdout worked because it used the dump() javascript function, which certainly use the file descriptor 1, and not /dev/stdout directly.

— You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub https://github.com/laurentj/slimerjs/issues/478#issuecomment-218417828

eolalde commented 8 years ago

Hi again @laurentj & @MarkR42 !!

Some updates on this issue, I've done some investigation on my end, and YES, by default Node.js will pipe the streams to other file descriptors available to the child process, and it seems like the standard is:

fd/0 -> stdin fd/1 -> stdout fd/2 -> stderr

All found on Node's docs: https://nodejs.org/dist/latest-v4.x/docs/api/child_process.html

As a side note, I found another way to drive Slimer through Node.js as a separate process using Slimer's webServer module, and this really works. I gotta say, for such a popular pair of tools in Web Development I was surprised I couldn't find any real working interface between Node.js and Slimer that would allow you to send your Slimerjs API instructions.. Do you know of any tool that can drive Slimer in a Slimer/Phantom fashion? (Given that CasperJS runs on it's own and Spooky which was the Node driver is not really maintained)

So, if I this driver I'm putting together works good enough I'll share with the community..

Thanks for all!

a-lucas commented 7 years ago

I actually have have a similar issue with 10.0.1, if I call `system.stdout.write('something'); before page is called.

Also stdout works, but stderr fails silently.

mw2852 commented 7 years ago

I have the same issue! What is the latest version where stdout.write still uses javascript dump()? Also, would it be possible to return to dump() or is it not compatible anymore?

AndrewGrachov commented 7 years ago

Confirming

Having code:

var webpageModule = require("webpage");
var system = require("system");
var a = system.stdin.read();
var page = require("webpage").create();
page.open("https://google.com")
    .then(function(status){
         if (status == "success") {
             console.log("The title of the page is: "+ page.title);
         }
         else {
             console.log("Sorry, the page is not loaded");
         }
         page.render('preview.png')
         page.close();
         phantom.exit();
    })

Then

xvfb-run slimerjs test2.js

Drops off on line

system.stdin.read();
Script Error: path does not exist: /dev/stdin
       Stack:
         -> resource://slimerjs/addon-sdk/sdk/io/file.js: 80
         -> resource://slimerjs/addon-sdk/sdk/io/file.js: 80 (in function friendlyError)
         -> resource://slimerjs/addon-sdk/sdk/io/file.js: 372 (in function open)
         -> resource://slimerjs/slimer-sdk/system.js: 251 (in function .get)
         -> file:///opt/preview-micro/test2.js: 3

This happens inside docker container Ubuntu 14.04

AndrewGrachov commented 7 years ago

Looks like stdout/stdint don't work inside X environment, like xvfb-run, because thy don't have these descriptors.

misu200 commented 7 years ago

Having the same problem . Can't migrate some Node and Casperjs/Phantomjs application(child proces stuff) to SlimerJS because although I have no problems running the app on Mac ...cant running ( headless or not ) on a Linux box because of this bug. I ve tried to downgrade to SlimerJS 0.9.6 but it s requiring to downgrade the Firefox also to an older version .... I guess I need to use the SlimerJS WebServer module to control SlimerJS from Node ?

laurentj commented 6 years ago

I made some investigations after reviewing issue #646 : in nodejs /dev/stdout etc are in fact links to a socket. For example, on my linux box, from a js script launch by nodejs, /dev/stdout is socket:[265577]. So to write to stdout and read from stdin, we should use these sockets. I should now find how to use this existing socket with the gecko internal API.