Exemplo n.º 1
0
    def __init__(self, socket=None, wait=True):
        """
        Spawns a node.js subprocess that listens on a TCP socket.
        A :class:`zombie.proxy.client.ZombieProxyClient` streams data to
        the server, which evaluates it as Javascript, passes it on to
        a zombie.js Browser object, and returns the results.

        :param socket: a (random, by default) filepath representing the
                       intended TCP socket location
        :param wait: when True, wait until the node.js subprocess is responsive
                    via the specified TCP socket.
        """
        socket = socket or '/tmp/zombie-%s.sock' % random.randint(0, 10000)

        self.socket = socket
        #
        # Spawn the node proxy server in a subprocess.
        # This is a simple socket server that listens for data,
        # evaluates it as Javascript, and passes the eval'ed
        # input to a Zombie.js Browser object.
        #
        args = ['env', 'node', proxy_path, self.socket]
        self.child = subprocess.Popen(
            args,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT
        )
        self.child.stdin.close()

        if wait:
            # Wait until we can ping the node.js server
            client = ZombieProxyClient(socket)
            retries = 30
            while True:
                retries -= 1
                if retries < 0:  # pragma: nocover
                    raise RuntimeError(
                        "The proxy server has not replied within 3 seconds."
                    )
                try:
                    assert client.ping() == 'pong'
                except (SocketError, AssertionError):
                    pass
                else:
                    break
                time.sleep(.1)

        #
        # Start a thread to monitor and redirect the
        # subprocess stdout and stderr to the console.
        #
        PipeWorker(self.child.stdout).start()
Exemplo n.º 2
0
    def __init__(self, socket=None, wait=True):
        """
        Spawns a node.js subprocess that listens on a TCP socket.
        A :class:`zombie.proxy.client.ZombieProxyClient` streams data to
        the server, which evaluates it as Javascript, passes it on to
        a zombie.js Browser object, and returns the results.

        :param socket: a (random, by default) filepath representing the
                       intended TCP socket location
        :param wait: when True, wait until the node.js subprocess is responsive
                    via the specified TCP socket.
        """
        socket = socket or '/tmp/zombie-%s.sock' % random.randint(0, 10000)

        self.socket = socket

        # Kill the node process when finished
        atexit.register(__kill_node_processes__)

        #
        # Spawn the node proxy server in a subprocess.
        # This is a simple socket server that listens for data,
        # evaluates it as Javascript, and passes the eval'ed
        # input to a Zombie.js Browser object.
        #
        args = ['env', 'node', proxy_path, self.socket]
        self.child = subprocess.Popen(
            args,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT
        )
        self.child.stdin.close()
        PipeWorker(self.child.stdout).start()
        if wait:
            # Wait until we can ping the node.js server
            client = ZombieProxyClient(socket)
            retries = 30
            while True:
                retries -= 1
                if retries < 0:  # pragma: nocover
                    raise RuntimeError(
                        "The proxy server has not replied within 3 seconds."
                    )
                try:
                    assert client.ping() == 'pong'
                except (SocketError, AssertionError):
                    pass
                else:
                    break
                time.sleep(.1)
Exemplo n.º 3
0
    def __init__(self, socket=None, wait=True):
        """
        Spawns a node.js subprocess that listens on a TCP socket.
        A :class:`zombie.proxy.client.ZombieProxyClient` streams data to
        the server, which evaluates it as Javascript, passes it on to
        a zombie.js Browser object, and returns the results.

        :param socket: a (random, by default) filepath representing the
                       intended TCP socket location, or (on Windows) a tuple
                       containing a host and a port name (defaults to
                       ("127.0.0.1", 40140).
        :param wait: when True, wait until the node.js subprocess is responsive
                    via the specified TCP socket.
        """
        # no file based unix socket on windows
        if sys.platform == "win32":
            socket = socket or ("127.0.0.1", 40140)
        else:
            socket = socket or '/tmp/zombie-%s.sock' % random.randint(0, 10000)

        self.socket = socket

        # Kill the node process when finished
        atexit.register(__kill_node_processes__)

        #
        # Spawn the node proxy server in a subprocess.
        # This is a simple socket server that listens for data,
        # evaluates it as Javascript, and passes the eval'ed
        # input to a Zombie.js Browser object.
        #
        if sys.platform == "win32":
            # no env on windows,
            # just make sure that node is on the path
            # also no Unix file socket on windows, thus
            # only the port from the INET socket given as argument
            args = ['node', proxy_path, str(self.socket[1])]
        else:
            args = ['env', 'node', proxy_path, self.socket]
        self.child = subprocess.Popen(args,
                                      stdin=subprocess.PIPE,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.STDOUT)
        self.child.stdin.close()
        PipeWorker(self.child.stdout).start()
        if wait:
            # Wait until we can ping the node.js server
            client = ZombieProxyClient(socket)
            retries = 30
            while True:
                retries -= 1
                if retries < 0:  # pragma: nocover
                    raise RuntimeError(
                        "The proxy server has not replied within 3 seconds.")
                try:
                    assert client.ping() == 'pong'
                except (SocketError, AssertionError):
                    pass
                else:
                    break
                time.sleep(.1)
Exemplo n.º 4
0
class ZombieProxyClientTests(WebServerTestCase):
    def setUp(self):
        super(ZombieProxyClientTests, self).setUp()
        # Note, As a singleton so it will be created once, not in every test.
        self.server = ZombieProxyServer()
        self.client = ZombieProxyClient(self.server.socket)

    def tearDown(self):
        super(ZombieProxyClientTests, self).tearDown()

    def test_simple_json(self):
        obj = {
            'foo': 'bar',
            'test': 500
        }
        self.assertEqual(obj, self.client.json(obj))

    def test_malformed_command(self):
        with self.assertRaises(NodeError):
            self.client.json("banana")

    def test_nowait(self):
        self.assertEqual('Test', self.client.nowait("result = 'Test';"))

    def test_wait(self):
        self.client.wait('browser.visit', self.base_url)

    def test_wait_error(self):
        with self.assertRaises(NodeError):
            self.client.wait('browser.visit', self.base_url + 'notfound')

    def test_ping(self):
        self.assertEqual("pong", self.client.ping())

    def test_cleanup(self):
        client = self.client
        self.assertEqual(1, client.json('browser.testing = 1'))
        client.cleanup()
        self.assertFalse(client.json('"testing" in browser'))

    def test_create_element(self):
        client = self.client
        client.wait('browser.visit', self.base_url)
        self.assertEqual(
            0,
            client.create_element('browser.query', ('form',)).index)
        self.assertEqual(
            1,
            client.create_element('browser.query', ('form',)).index)

    def test_create_element_attribute(self):
        client = self.client
        client.wait('browser.visit', self.base_url)
        self.assertEqual(
            0, client.create_element('browser.html').index)

    def test_create_elements(self):
        client = self.client
        client.wait('browser.visit', self.base_url)
        res = client.create_elements('browser.queryAll', ('input', ))
        self.assertEqual(list(range(6)), [x.index for x in res])