Exemple #1
0
 async def start(self, options: Dict = None, **kwargs: Any) -> None:
     'Start coverage measurement.'
     options = merge_dict(options, kwargs)
     if self._enabled:
         raise PageError('JSCoverage is always enabled.')
     self._resetOnNavigation = (True if ('resetOnNavigation' not in options)
                                else bool(options['resetOnNavigation']))
     self._enabled = True
     self._scriptURLs.clear()
     self._scriptSources.clear()
     self._eventListeners = [
         helper.addEventListener(
             self._client, 'Debugger.scriptParsed',
             (lambda e: asyncio.ensure_future(self._onScriptParsed(e)))),
         helper.addEventListener(self._client,
                                 'Runtime.executionContextsCleared',
                                 self._onExecutionContextsCleared)
     ]
     (await self._client.send('Profiler.enable'))
     (await self._client.send('Profiler.startPreciseCoverage', {
         'callCount': False,
         'detailed': True,
     }))
     (await self._client.send('Debugger.enable'))
     (await self._client.send('Debugger.setSkipAllPauses', {
         'skip': True,
     }))
Exemple #2
0
 def __init__(self,
              frameManager: FrameManager,
              frame: Frame,
              timeout: int,
              options: Dict = None,
              **kwargs: Any) -> None:
     'Make new navigator watcher.'
     options = merge_dict(options, kwargs)
     self._validate_options(options)
     self._frameManager = frameManager
     self._frame = frame
     self._initialLoaderId = frame._loaderId
     self._timeout = timeout
     self._hasSameDocumentNavigation = False
     self._eventListeners = [
         helper.addEventListener(self._frameManager,
                                 FrameManager.Events.LifecycleEvent,
                                 self._checkLifecycleComplete),
         helper.addEventListener(
             self._frameManager,
             FrameManager.Events.FrameNavigatedWithinDocument,
             self._navigatedWithinDocument),
         helper.addEventListener(self._frameManager,
                                 FrameManager.Events.FrameDetached,
                                 self._checkLifecycleComplete)
     ]
     self._loop = self._frameManager._client._loop
     self._lifecycleCompletePromise = self._loop.create_future()
     self._navigationPromise = self._loop.create_task(
         asyncio.wait(
             [self._lifecycleCompletePromise,
              self._createTimeoutPromise()],
             return_when=concurrent.futures.FIRST_COMPLETED))
     self._navigationPromise.add_done_callback(
         (lambda fut: self._cleanup()))
Exemple #3
0
    def __init__(self, frameManager: FrameManager, frame: Frame, timeout: int,
                 options: Dict = None, **kwargs: Any) -> None:
        """Make new navigator watcher."""
        options = merge_dict(options, kwargs)
        self._validate_options(options)
        self._frameManeger = frameManager
        self._frame = frame
        self._initialLoaderId = frame._loaderId
        self._timeout = timeout
        self._eventListeners = [
            helper.addEventListener(
                self._frameManeger,
                FrameManager.Events.LifecycleEvent,
                self._checkLifecycleComplete,
            ),
            helper.addEventListener(
                self._frameManeger,
                FrameManager.Events.FrameDetached,
                self._checkLifecycleComplete,
            ),
        ]
        loop = asyncio.get_event_loop()
        self._lifecycleCompletePromise = loop.create_future()

        self._navigationPromise = asyncio.ensure_future(asyncio.wait([
            self._lifecycleCompletePromise,
            self._createTimeoutPromise(),
        ], return_when=concurrent.futures.FIRST_COMPLETED))
        self._navigationPromise.add_done_callback(
            lambda fut: self._cleanup())
 async def start(self, options: Dict = None, **kwargs: Any) -> None:
     """Start coverage measurement."""
     options = merge_dict(options, kwargs)
     if self._enabled:
         raise PageError('JSCoverage is always enabled.')
     self._resetOnNavigation = (True if 'resetOnNavigation' not in options
                                else bool(options['resetOnNavigation']))
     self._reportAnonymousScript = bool(
         options.get('reportAnonymousScript'))  # noqa: E501
     self._enabled = True
     self._scriptURLs.clear()
     self._scriptSources.clear()
     self._eventListeners = [
         helper.addEventListener(
             self._client, 'Debugger.scriptParsed',
             lambda e: self._client._loop.create_task(
                 self._onScriptParsed(e))),
         helper.addEventListener(self._client,
                                 'Runtime.executionContextsCleared',
                                 self._onExecutionContextsCleared),
     ]
     await self._client.send('Profiler.enable')
     await self._client.send('Profiler.startPreciseCoverage', {
         'callCount': False,
         'detailed': True
     })
     await self._client.send('Debugger.enable')
     await self._client.send('Debugger.setSkipAllPauses', {'skip': True})
    def __init__(self,
                 frameManager: FrameManager,
                 frame: Frame,
                 timeout: int,
                 options: Dict = None,
                 **kwargs: Any) -> None:
        """Make new navigator watcher."""
        options = merge_dict(options, kwargs)
        self._validate_options(options)
        self._frameManeger = frameManager
        self._frame = frame
        self._initialLoaderId = frame._loaderId
        self._timeout = timeout
        self._eventListeners = [
            helper.addEventListener(
                self._frameManeger,
                FrameManager.Events.LifecycleEvent,
                self._checkLifecycleComplete,
            ),
            helper.addEventListener(
                self._frameManeger,
                FrameManager.Events.FrameDetached,
                self._checkLifecycleComplete,
            ),
        ]
        loop = asyncio.get_event_loop()
        self._lifecycleCompletePromise = loop.create_future()

        self._navigationPromise = asyncio.ensure_future(
            asyncio.wait([
                self._lifecycleCompletePromise,
                self._createTimeoutPromise(),
            ],
                         return_when=concurrent.futures.FIRST_COMPLETED))
        self._navigationPromise.add_done_callback(lambda fut: self._cleanup())
    def __init__(self, frameManager: FrameManager, frame: Frame,
                 waitUntil: str, timeout: int) -> None:
        if isinstance(waitUntil, list):
            waitUntil = waitUntil[::]
        elif isinstance(waitUntil, str):
            waitUntil = [waitUntil]
        if "documentloaded" in waitUntil:
            logging.getLogger(__name__).warning(
                '`documentloaded` option is no longer supported. '
                'Use `domcontentloaded` instead.')
        self._hasSameDocumentNavigation = False
        self._expectedLifecycle: List[str] = []
        for value in waitUntil:
            protocolEvent = pyppeteerToProtocolLifecycle.get(value)
            if protocolEvent is None:
                raise ValueError(
                    f'Unknown value for options.waitUntil: {value}')
            self._expectedLifecycle.append(protocolEvent)

        self._maximumTimer = None
        self._timeoutOrTermination = None
        self._frameManager = frameManager
        self._loop = self._frameManager._client._loop
        self._frame = frame
        self._initialLoaderId = frame._loaderId
        self._timeout = timeout
        self._navigationRequest = None
        self._eventListeners = [
            helper.addEventListener(frameManager._client,
                                    CDPSession.Events.Disconnected,
                                    lambda: self._terminate(NetworkError(
                                        'Navigation failed because browser has disconnected!'))
                                    ),
            helper.addEventListener(self._frameManager,
                                    FrameManager.Events.LifecycleEvent,
                                    self._checkLifecycleComplete),
            helper.addEventListener(self._frameManager,
                                    FrameManager.Events.FrameNavigatedWithinDocument,
                                    self._navigatedWithinDocument),
            helper.addEventListener(self._frameManager,
                                    FrameManager.Events.FrameDetached,
                                    self._onFrameDetached),
            helper.addEventListener(self._frameManager.NetworkManager,
                                    NetworkManager.Events.Request,
                                    self._onRequest),

        ]
        self._timeoutPromise = self._createTimeoutPromise()
        self._sameDocumentNavigationPromise = self._loop.create_future()
        self._lifecyclePromise = self._loop.create_future()
        self._newDocumentNavigationPromise = self._loop.create_future()
        self._terminationPromise = self._loop.create_future()
        self._checkLifecycleComplete()
Exemple #7
0
 async def start(self, options: Dict = None, **kwargs: Any) -> None:
     'Start coverage measurement.'
     options = merge_dict(options, kwargs)
     if self._enabled:
         raise PageError('CSSCoverage is already enabled.')
     self._resetOnNavigation = (True if (
         'resetOnNavigation' not in options) else bool(options['resetOnNavigation']))
     self._enabled = True
     self._stylesheetURLs.clear()
     self._stylesheetSources.clear()
     self._eventListeners = [helper.addEventListener(self._client, 'CSS.styleSheetAdded', (lambda e: self._client._loop.create_task(
         self._onStyleSheet(e)))), helper.addEventListener(self._client, 'Runtime.executionContextsCleared', self._onExecutionContextsCleared)]
     (await self._client.send('DOM.enable'))
     (await self._client.send('CSS.enable'))
     (await self._client.send('CSS.startRuleUsageTracking'))
Exemple #8
0
    async def waitForNavigation(self,
                                options: dict = None,
                                **kwargs: Any) -> Optional[Response]:
        """Wait for navigation.

        Available options are same as :meth:`goto` method.
        """
        options = merge_dict(options, kwargs)
        mainFrame = self._frameManager.mainFrame
        if mainFrame is None:
            raise PageError('No main frame.')
        timeout = options.get('timeout', self._defaultNavigationTimeout)
        watcher = NavigatorWatcher(self._frameManager, mainFrame, timeout,
                                   options)
        responses: Dict[str, Response] = dict()
        listener = helper.addEventListener(
            self._networkManager, NetworkManager.Events.Response,
            lambda response: responses.__setitem__(response.url, response))
        result = await watcher.navigationPromise()
        helper.removeEventListeners([listener])
        error = result[0].pop().exception()
        if error:
            raise error

        response = responses.get(self.url, None)
        return response
Exemple #9
0
    async def waitForNavigation(self, options: dict = None, **kwargs: Any
                                ) -> Optional[Response]:
        """Wait for navigation.

        Available options are same as :meth:`goto` method.
        """
        options = merge_dict(options, kwargs)
        mainFrame = self._frameManager.mainFrame
        if mainFrame is None:
            raise PageError('No main frame.')
        timeout = options.get('timeout', self._defaultNavigationTimeout)
        watcher = NavigatorWatcher(self._frameManager, mainFrame, timeout,
                                   options)
        responses: Dict[str, Response] = dict()
        listener = helper.addEventListener(
            self._networkManager,
            NetworkManager.Events.Response,
            lambda response: responses.__setitem__(response.url, response)
        )
        result = await watcher.navigationPromise()
        helper.removeEventListeners([listener])
        error = result[0].pop().exception()
        if error:
            raise error

        response = responses.get(self.url, None)
        return response
Exemple #10
0
    async def goto(self,
                   url: str,
                   options: dict = None,
                   **kwargs: Any) -> Optional[Response]:
        """Go to the url.

        :arg string url: URL to go.
        """
        options = merge_dict(options, kwargs)
        referrer = self._networkManager.extraHTTPHeaders().get('referer', '')
        requests: Dict[str, Request] = dict()
        eventListeners = [
            helper.addEventListener(
                self._networkManager, NetworkManager.Events.Request,
                lambda request: requests.__setitem__(request.url, request))
        ]

        mainFrame = self._frameManager.mainFrame
        if mainFrame is None:
            raise PageError('No main frame.')
        watcher = NavigatorWatcher(self._frameManager, mainFrame, options)

        result = await self._navigate(url, referrer)
        if result is not None:
            raise PageError(result)
        result = await watcher.navigationPromise()
        watcher.cancel()
        helper.removeEventListeners(eventListeners)
        error = result[0].pop().exception()  # type: ignore
        if error:
            raise error

        request = requests.get(mainFrame.url)
        return request.response if request else None
Exemple #11
0
    async def goto(self,
                   url: str,
                   options: dict = None,
                   **kwargs: Any) -> Optional[Response]:
        """Got to url."""
        if options is None:
            options = dict()
        options.update(kwargs)
        watcher = NavigatorWatcher(self._client, self._ignoreHTTPSErrors,
                                   options)
        responses: Dict[str, Response] = dict()
        listener = helper.addEventListener(
            self._networkManager, NetworkManager.Events.Response,
            lambda response: responses.__setitem__(response.url, response))
        navigationPromise = watcher.waitForNavigation()
        referrer = self._networkManager.extraHTTPHeaders().get('referer', '')

        try:
            await self._client.send('Page.navigate',
                                    dict(url=url, referrer=referrer))
        except Exception:
            watcher.cancel()
            helper.removeEventListeners([listener])
            raise
        error = await navigationPromise
        helper.removeEventListeners([listener])
        if error:
            raise error

        if self._frameManager.isMainFrameLoadingFailed():
            raise PageError('Failed to navigate: ' + url)
        return responses.get(self.url)
Exemple #12
0
    async def waitForNavigation(self) -> None:
        """Wait until navigatoin completes."""
        self._requestIds: Set[str] = set()
        self._eventListeners: List[dict] = list()
        navigationPromises = list()
        loop = asyncio.get_event_loop()

        def watchdog_cb(fut: Awaitable) -> None:
            self._raise_error(asyncio.TimeoutError(
                'Navigation Timeout Exceeded: {} ms exceeded'.format(
                    self._timeout)
            ))

        watchdog: asyncio.Future = asyncio.ensure_future(
            asyncio.sleep(self._timeout / 1000))
        self._maximumTimer = watchdog
        watchdog.add_done_callback(watchdog_cb)
        navigationPromises.append(watchdog)

        if not self._ignoreHTTPSErrors:
            certificateError = loop.create_future()
            self._eventListeners.append(
                helper.addEventListener(
                    self._client, 'Security.certificateError',
                    lambda event: certificateError.set_exception(
                        NetworkError('SSL Certificate error: ' +
                                     str(event.get('errorType')))
                    )
                )
            )
            navigationPromises.append(certificateError)

        if self._waitUntil == 'load':
            loadEventFired = loop.create_future()
            self._eventListeners.append(
                helper.addEventListener(
                    self._client, 'Page.loadEventFired',
                    lambda event: loadEventFired.set_result(None)
                )
            )
            navigationPromises.append(loadEventFired)
        else:
            self._eventListeners.extend((
                helper.addEventListener(self._client, 'Network.requestWillBeSent', self._onLoadingStarted),  # noqa
                helper.addEventListener(self._client, 'Network.loadingFinished', self._onLoadingCompleted),  # noqa
                helper.addEventListener(self._client, 'Network.loadingFailed', self._onLoadingCompleted),  # noqa
                helper.addEventListener(self._client, 'Network.webSocketCreated', self._onLoadingStarted),  # noqa
                helper.addEventListener(self._client, 'Network.webSocketClosed', self._onLoadingCompleted),  # noqa
            ))
            networkIdle = loop.create_future()
            self._networkIdleCallback = lambda f: networkIdle.set_result(None)
            navigationPromises.append(networkIdle)

        await asyncio.wait(navigationPromises,
                           return_when=concurrent.futures.FIRST_COMPLETED)
        if not watchdog.done():
            watchdog.remove_done_callback(watchdog_cb)
        self._cleanup()
Exemple #13
0
    async def goto(self,
                   url: str,
                   options: dict = None,
                   **kwargs: Any) -> Optional[Response]:
        """Go to the ``url``.

        :arg string url: URL to navigate page to. The url should include
            scheme, e.g. ``https://``.

        Available options are:

        * ``timeout`` (int): Maximum navigation time in milliseconds, defaults
          to 30 seconds, pass ``0`` to desable timeout. The default value can
          be changed by using the :meth:`setDefaultNavigationTimeout` method.
        * ``waitUntil`` (str|List[str]): When to consider navigation succeeded,
          defaults to ``load``. Given a list of event strings, navigation is
          considered to be successful after all events have been fired. Events
          can be either:

          * ``load``: when ``load`` event is fired.
          * ``documentloaded``: when the ``DOMContentLoaded`` event is fired.
          * ``networkidle0``: when there are no more than 0 network connections
            for at least 500 ms.
          * ``networkidle0``: when there are no more than 2 network connections
            for at least 500 ms.
        """
        options = merge_dict(options, kwargs)
        referrer = self._networkManager.extraHTTPHeaders().get('referer', '')
        requests: Dict[str, Request] = dict()
        eventListeners = [
            helper.addEventListener(
                self._networkManager, NetworkManager.Events.Request,
                lambda request: requests.__setitem__(request.url, request))
        ]

        mainFrame = self._frameManager.mainFrame
        if mainFrame is None:
            raise PageError('No main frame.')
        timeout = options.get('timeout', self._defaultNavigationTimeout)
        watcher = NavigatorWatcher(self._frameManager, mainFrame, timeout,
                                   options)

        result = await self._navigate(url, referrer)
        if result is not None:
            raise PageError(result)
        result = await watcher.navigationPromise()
        watcher.cancel()
        helper.removeEventListeners(eventListeners)
        error = result[0].pop().exception()  # type: ignore
        if error:
            raise error

        request = requests.get(mainFrame.url)
        return request.response if request else None
Exemple #14
0
 async def start(self, options: Dict = None, **kwargs: Any) -> None:
     """Start coverage measurement."""
     options = merge_dict(options, kwargs)
     if self._enabled:
         raise PageError('CSSCoverage is already enabled.')
     self._resetOnNavigation = (True if 'resetOnNavigation' not in options
                                else bool(options['resetOnNavigation']))
     self._enabled = True
     self._stylesheetURLs.clear()
     self._stylesheetSources.clear()
     self._eventListeners = [
         helper.addEventListener(
             self._client, 'CSS.styleSheetAdded',
             lambda e: asyncio.ensure_future(self._onStyleSheet(e))),
         helper.addEventListener(
             self._client, 'Runtime.executionContextsCleared',
             self._onExecutionContextsCleared),
     ]
     await self._client.send('DOM.enable')
     await self._client.send('CSS.enable')
     await self._client.send('CSS.startRuleUsageTracking')
Exemple #15
0
    async def goto(self, url: str, options: dict = None, **kwargs: Any
                   ) -> Optional[Response]:
        """Go to the ``url``.

        :arg string url: URL to navigate page to. The url should include
            scheme, e.g. ``https://``.

        Available options are:

        * ``timeout`` (int): Maximum navigation time in milliseconds, defaults
          to 30 seconds, pass ``0`` to desable timeout. The default value can
          be changed by using the :meth:`setDefaultNavigationTimeout` method.
        * ``waitUntil`` (str|List[str]): When to consider navigation succeeded,
          defaults to ``load``. Given a list of event strings, navigation is
          considered to be successful after all events have been fired. Events
          can be either:

          * ``load``: when ``load`` event is fired.
          * ``documentloaded``: when the ``DOMContentLoaded`` event is fired.
          * ``networkidle0``: when there are no more than 0 network connections
            for at least 500 ms.
          * ``networkidle2``: when there are no more than 2 network connections
            for at least 500 ms.
        """
        options = merge_dict(options, kwargs)
        referrer = self._networkManager.extraHTTPHeaders().get('referer', '')
        requests: Dict[str, Request] = dict()
        eventListeners = [helper.addEventListener(
            self._networkManager, NetworkManager.Events.Request,
            lambda request: requests.__setitem__(request.url, request)
        )]

        mainFrame = self._frameManager.mainFrame
        if mainFrame is None:
            raise PageError('No main frame.')
        timeout = options.get('timeout', self._defaultNavigationTimeout)
        watcher = NavigatorWatcher(self._frameManager, mainFrame, timeout,
                                   options)

        result = await self._navigate(url, referrer)
        if result is not None:
            raise PageError(result)
        result = await watcher.navigationPromise()
        watcher.cancel()
        helper.removeEventListeners(eventListeners)
        error = result[0].pop().exception()  # type: ignore
        if error:
            raise error

        request = requests.get(mainFrame.url)
        return request.response if request else None
Exemple #16
0
 async def start(self, options: Dict = None, **kwargs: Any) -> None:
     """Start coverage measurement."""
     options = merge_dict(options, kwargs)
     if self._enabled:
         raise PageError('JSCoverage is always enabled.')
     self._resetOnNavigation = (True if 'resetOnNavigation' not in options
                                else bool(options['resetOnNavigation']))
     self._enabled = True
     self._scriptURLs.clear()
     self._scriptSources.clear()
     self._eventListeners = [
         helper.addEventListener(
             self._client, 'Debugger.scriptParsed',
             lambda e: asyncio.ensure_future(self._onScriptParsed(e))),
         helper.addEventListener(
             self._client, 'Runtime.executionContextsCleared',
             self._onExecutionContextsCleared),
     ]
     await self._client.send('Profiler.enable')
     await self._client.send('Profiler.startPreciseCoverage',
                             {'callCount': False, 'detailed': True})
     await self._client.send('Debugger.enable')
     await self._client.send('Debugger.setSkipAllPauses', {'skip': True})
Exemple #17
0
    async def ensureInitialPage(self, browser: Browser) -> None:
        'Wait for initial page target to be created.'
        for target in browser.targets():
            if (target.type == 'page'):
                return
        initialPagePromise = self._loop.create_future()

        def initialPageCallback() -> None:
            initialPagePromise.set_result(True)

        def check_target(target: Target) -> None:
            if (target.type == 'page'):
                initialPageCallback()

        listeners = [addEventListener(browser, 'targetcreated', check_target)]
        (await initialPagePromise)
        removeEventListeners(listeners)
Exemple #18
0
 async def waitForNavigation(self, options: dict = None, **kwargs: Any
                             ) -> Optional[Response]:
     """Wait navigation completes."""
     if options is None:
         options = dict()
     options.update(kwargs)
     watcher = NavigatorWatcher(self._client, self._ignoreHTTPSErrors,
                                options)
     responses: Dict[str, Response] = dict()
     listener = helper.addEventListener(
         self._networkManager,
         NetworkManager.Events.Response,
         lambda response: responses.__setitem__(response.url, response)
     )
     await watcher.waitForNavigation()
     helper.removeEventListeners([listener])
     return responses.get(self.url)
Exemple #19
0
    async def ensureInitialPage(self, browser: Browser) -> None:
        """Wait for initial page target to be created."""
        for target in browser.targets():
            if target.type == 'page':
                return

        initialPagePromise = self._loop.create_future()

        def initialPageCallback() -> None:
            initialPagePromise.set_result(True)

        def check_target(target: Target) -> None:
            if target.type == 'page':
                initialPageCallback()

        listeners = [addEventListener(browser, 'targetcreated', check_target)]
        await initialPagePromise
        removeEventListeners(listeners)