Example #1
0
 async def evaluateOnNewDocument(self, pageFunction: str,
                                 *args: str) -> None:
     """Evaluate js-function on new document."""
     source = helper.evaluationString(pageFunction, *args)
     await self._client.send('Page.addScriptToEvaluateOnNewDocument', {
         'source': source,
     })
Example #2
0
 async def _rawEvaluate(self, pageFunction: str, *args: Any) -> dict:
     if not args:
         expression = helper.evaluationString(pageFunction, *args)
         contextId = self._defaultContextId
         obj = await self._client.send(
             'Runtime.evaluate', {
                 'expression': expression,
                 'contextId': contextId,
                 'returnByValue': False,
                 'awaitPromise': True,
             })
     else:
         obj = await self._client.send(
             'Runtime.callFunctionOn', {
                 'functionDeclaration': pageFunction,
                 'executionContextId': self._defaultContextId,
                 'arguments': [self._convertArgument(arg) for arg in args],
                 'returnByValue': False,
                 'awaitPromise': True
             })
     exceptionDetails = obj.get('exceptionDetails', dict())
     remoteObject = obj.get('result', dict())
     if exceptionDetails:
         raise BrowserError('Evaluation failed: ' +
                            helper.getExceptionMessage(exceptionDetails) +
                            f'\npageFunction:\n{pageFunction}')
     return remoteObject
Example #3
0
    async def exposeFunction(self, name: str,
                             puppeteerFunction: Callable) -> None:
        """Execute function on this page."""
        if self._pageBindings[name]:
            raise PageError(f'Failed to add page binding with name {name}: '
                            'window["{name}"] already exists!')
        self._pageBindings[name] = puppeteerFunction

        addPageBinding = '''
function addPageBinding(bindingName) {
  window[bindingName] = async(...args) => {
    const me = window[bindingName];
    let callbacks = me['callbacks'];
    if (!callbacks) {
      callbacks = new Map();
      me['callbacks'] = callbacks;
    }
    const seq = (me['lastSeq'] || 0) + 1;
    me['lastSeq'] = seq;
    const promise = new Promise(fulfill => callbacks.set(seq, fulfill));
    // eslint-disable-next-line no-console
    console.debug('driver:page-binding', JSON.stringify({name: bindingName, seq, args}));
    return promise;
  };
}
        '''  # noqa: E501
        expression = helper.evaluationString(addPageBinding, name)
        await self._client.send('Page.addScriptToEvaluateOnNewDocument',
                                {'source': expression})
        await self._client.send('Runtime.evaluate', {
            'expression': expression,
            'returnByValue': True
        })
Example #4
0
    async def _onConsoleAPI(self, event: dict) -> None:
        _args = event.get('args', [])
        if (event.get('type') == 'debug' and _args
                and _args[0]['value'] == 'driver:page-binding'):
            obj = json.loads(_args[1]['value'])
            name = obj.get('name')
            seq = obj.get('seq')
            args = obj.get('args')
            result = await self._pageBindings[name](*args)

            deliverResult = '''
function deliverResult(name, seq, result) {
  window[name]['callbacks'].get(seq)(result)
  window[name]['callbacks'].delete(seq)
}
            '''
            expression = helper.evaluationString(deliverResult, name, seq,
                                                 result)
            await self._client.send('Runtime.evaluate',
                                    {'expression': expression})
            return

        if not self.listeners(Page.Events.Console):
            for arg in _args:
                await helper.releaseObject(self._client, arg)
            return

        _values = []
        for arg in _args:
            _values.append(
                asyncio.ensure_future(helper.valueFromRemoteObject(arg)))
        values = await asyncio.gather(*_values)
        self.emit(Page.Events.Console, *values)
Example #5
0
    async def evaluateOnNewDocument(self, pageFunction: str,
                                    *args: str) -> None:
        """Add a JavaScript function to the document.

        This function would be invoked in one of the following scenarios:

        * whenever the page is navigated
        * whenever the child frame is attached or navigated. Inthis case, the
          function is invoked in the context of the newly attached frame.
        """
        source = helper.evaluationString(pageFunction, *args)
        await self._client.send('Page.addScriptToEvaluateOnNewDocument', {
            'source': source,
        })
Example #6
0
    async def evaluateOnNewDocument(self, pageFunction: str, *args: str
                                    ) -> None:
        """Add a JavaScript function to the document.

        This function would be invoked in one of the following scenarios:

        * whenever the page is navigated
        * whenever the child frame is attached or navigated. Inthis case, the
          function is invoked in the context of the newly attached frame.
        """
        source = helper.evaluationString(pageFunction, *args)
        await self._client.send('Page.addScriptToEvaluateOnNewDocument', {
            'source': source,
        })
Example #7
0
    def _onConsoleAPI(self, event: dict) -> None:
        _args = event.get('args', [])
        if (event.get('type') == 'debug' and _args
                and _args[0]['value'] == 'driver:page-binding'):
            obj = json.loads(_args[1]['value'])
            name = obj.get('name')
            seq = obj.get('seq')
            args = obj.get('args')
            result = self._pageBindings[name](*args)

            deliverResult = '''
function deliverResult(name, seq, result) {
  window[name]['callbacks'].get(seq)(result);
  window[name]['callbacks'].delete(seq);
}
            '''
            expression = helper.evaluationString(deliverResult, name, seq,
                                                 result)
            asyncio.ensure_future(
                self._client.send(
                    'Runtime.evaluate', {
                        'expression': expression,
                        'contextId': event['executionContextId'],
                    }))
            return

        if not self.listeners(Page.Events.Console):
            for arg in _args:
                asyncio.ensure_future(helper.releaseObject(self._client, arg))
            return

        _id = event['executionContextId']
        values = []
        for arg in _args:
            values.append(self._frameManager.createJSHandle(_id, arg))

        textTokens = []
        for arg, value in zip(_args, values):
            if arg.get('objectId'):
                textTokens.append(value.toString())
            else:
                textTokens.append(str(helper.valueFromRemoteObject(arg)))

        message = ConsoleMessage(event['type'], ' '.join(textTokens), values)
        self.emit(Page.Events.Console, message)
Example #8
0
 async def _rawEvaluate(self, pageFunction: str, *args: str) -> dict:
     expression = helper.evaluationString(pageFunction, *args)
     contextId = self._defaultContextId
     obj = await self._client.send('Runtime.evaluate', {
         'expression': expression,
         'contextId': contextId,
         'returnByValue': False,
         'awaitPromise': True,
     })
     exceptionDetails = obj.get('exceptionDetails', dict())
     remoteObject = obj.get('result', dict())
     if exceptionDetails:
         raise BrowserError(
             'Evaluation failed: ' +
             helper.getExceptionMessage(exceptionDetails) +
             f'\npageFunction:\n{pageFunction}'
         )
     return remoteObject
Example #9
0
    def _onConsoleAPI(self, event: dict) -> None:
        _args = event.get('args', [])
        if (event.get('type') == 'debug' and _args and
                _args[0]['value'] == 'driver:page-binding'):
            obj = json.loads(_args[1]['value'])
            name = obj.get('name')
            seq = obj.get('seq')
            args = obj.get('args')
            result = self._pageBindings[name](*args)

            deliverResult = '''
function deliverResult(name, seq, result) {
  window[name]['callbacks'].get(seq)(result);
  window[name]['callbacks'].delete(seq);
}
            '''
            expression = helper.evaluationString(
                deliverResult, name, seq, result)
            asyncio.ensure_future(self._client.send('Runtime.evaluate', {
                'expression': expression,
                'contextId': event['executionContextId'],
            }))
            return

        if not self.listeners(Page.Events.Console):
            for arg in _args:
                asyncio.ensure_future(helper.releaseObject(self._client, arg))
            return

        _id = event['executionContextId']
        values = []
        for arg in _args:
            values.append(self._frameManager.createJSHandle(_id, arg))

        textTokens = []
        for arg, value in zip(_args, values):
            if arg.get('objectId'):
                textTokens.append(value.toString())
            else:
                textTokens.append(str(helper.valueFromRemoteObject(arg)))

        message = ConsoleMessage(event['type'], ' '.join(textTokens), values)
        self.emit(Page.Events.Console, message)
Example #10
0
    async def exposeFunction(self, name: str, pyppeteerFunction: Callable
                             ) -> None:
        """Add python function to the browser's ``window`` object as ``name``.

        Registered function can be called from chrome process.

        :arg string name: Name of the function on the window object.
        :arg Callable pyppeteerFunction: Function which will be called on
                                         python process.
        """
        if self._pageBindings.get(name):
            raise PageError(f'Failed to add page binding with name {name}: '
                            f'window["{name}"] already exists!')
        self._pageBindings[name] = pyppeteerFunction

        addPageBinding = '''
function addPageBinding(bindingName) {
  window[bindingName] = async(...args) => {
    const me = window[bindingName];
    let callbacks = me['callbacks'];
    if (!callbacks) {
      callbacks = new Map();
      me['callbacks'] = callbacks;
    }
    const seq = (me['lastSeq'] || 0) + 1;
    me['lastSeq'] = seq;
    const promise = new Promise(fulfill => callbacks.set(seq, fulfill));
    // eslint-disable-next-line no-console
    console.debug('driver:page-binding', JSON.stringify({name: bindingName, seq, args}));
    return promise;
  };
}
        '''  # noqa: E501
        expression = helper.evaluationString(addPageBinding, name)
        await self._client.send('Page.addScriptToEvaluateOnNewDocument',
                                {'source': expression})
        await asyncio.wait([
            frame.evaluate(expression, force_expr=True)
            for frame in self.frames
        ])
Example #11
0
    async def exposeFunction(self, name: str,
                             pyppeteerFunction: Callable) -> None:
        """Add python function to the browser's ``window`` object as ``name``.

        Registered function can be called from chrome process.

        :arg string name: Name of the function on the window object.
        :arg Callable pyppeteerFunction: Function which will be called on
                                         python process.
        """
        if self._pageBindings.get(name):
            raise PageError(f'Failed to add page binding with name {name}: '
                            f'window["{name}"] already exists!')
        self._pageBindings[name] = pyppeteerFunction

        addPageBinding = '''
function addPageBinding(bindingName) {
  window[bindingName] = async(...args) => {
    const me = window[bindingName];
    let callbacks = me['callbacks'];
    if (!callbacks) {
      callbacks = new Map();
      me['callbacks'] = callbacks;
    }
    const seq = (me['lastSeq'] || 0) + 1;
    me['lastSeq'] = seq;
    const promise = new Promise(fulfill => callbacks.set(seq, fulfill));
    // eslint-disable-next-line no-console
    console.debug('driver:page-binding', JSON.stringify({name: bindingName, seq, args}));
    return promise;
  };
}
        '''  # noqa: E501
        expression = helper.evaluationString(addPageBinding, name)
        await self._client.send('Page.addScriptToEvaluateOnNewDocument',
                                {'source': expression})
        await asyncio.wait([
            frame.evaluate(expression, force_expr=True)
            for frame in self.frames
        ])