From f154d537f7794a07b57904ecc8b0f76c60d24cd4 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Tue, 18 Jul 2017 19:11:37 -0700 Subject: [PATCH] Introduce page.goBack/page.goForward (#93) This patch introduces page.goBack/page.goForward methods to navigate the page history. References #89. --- docs/api.md | 16 +++++++++++++++- lib/Page.js | 32 +++++++++++++++++++++++++++++++- test/test.js | 18 ++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/docs/api.md b/docs/api.md index 518197bc8d7..86f0c6ed83e 100644 --- a/docs/api.md +++ b/docs/api.md @@ -35,6 +35,8 @@ * [page.evaluateOnInitialized(pageFunction, ...args)](#pageevaluateoninitializedpagefunction-args) * [page.focus(selector)](#pagefocusselector) * [page.frames()](#pageframes) + * [page.goBack(options)](#pagegobackoptions) + * [page.goForward(options)](#pagegoforwardoptions) * [page.httpHeaders()](#pagehttpheaders) * [page.injectFile(filePath)](#pageinjectfilefilepath) * [page.keyboard](#pagekeyboard) @@ -343,11 +345,23 @@ This is a shortcut for [page.mainFrame().evaluate()](#frameevaluatefun-args) met #### page.frames() - returns: <[Array]<[Frame]>> An array of all frames attached to the page. +#### page.goBack(options) +- `options` <[Object]> Navigation parameters, same as in [page.navigate](#pagenavigateurl-options). +- returns: <[Promise]<[Response]>> Promise which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect. If +can not go back, resolves to null. + +Navigate to the previous page in history. + +#### page.goForward(options) +- `options` <[Object]> Navigation parameters, same as in [page.navigate](#pagenavigateurl-options). +- returns: <[Promise]<[Response]>> Promise which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect. If +can not go back, resolves to null. + +Navigate to the next page in history. #### page.httpHeaders() - returns: <[Object]> Key-value set of additional http headers which will be sent with every request. - #### page.injectFile(filePath) - `filePath` <[string]> Path to the javascript file to be injected into page. - returns: <[Promise]> Promise which resolves when file gets successfully evaluated in page. diff --git a/lib/Page.js b/lib/Page.js index 7dc79d94f84..fce6eb860a4 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -291,7 +291,7 @@ class Page extends EventEmitter { /** * @param {!Object=} options - * @return {!Promise} + * @return {!Promise} */ async waitForNavigation(options) { const watcher = new NavigatorWatcher(this._client, this._networkManager, options); @@ -299,6 +299,36 @@ class Page extends EventEmitter { return responses.get(this.mainFrame().url()) || null; } + /** + * @param {!Object=} options + * @return {!Promise} + */ + async goBack(options) { + return this._go(-1, options); + } + + /** + * @param {!Object=} options + * @return {!Promise} + */ + async goForward(options) { + return this._go(+1, options); + } + + /** + * @param {!Object=} options + * @return {!Promise} + */ + async _go(delta, options) { + const history = await this._client.send('Page.getNavigationHistory'); + const entry = history.entries[history.currentIndex + delta]; + if (!entry) + return null; + const result = this.waitForNavigation(options); + this._client.send('Page.navigateToHistoryEntry', {entryId: entry.id}); + return result; + } + /** * @param {!Page.Viewport} viewport * @return {!Promise} diff --git a/test/test.js b/test/test.js index 7df8ef52c8d..8f5352859fd 100644 --- a/test/test.js +++ b/test/test.js @@ -438,6 +438,24 @@ describe('Puppeteer', function() { })); }); + describe('Page.goBack', function() { + it('should work', SX(async function() { + await page.navigate(EMPTY_PAGE); + await page.navigate(PREFIX + '/grid.html'); + + let response = await page.goBack(); + expect(response.ok).toBe(true); + expect(response.url).toContain(EMPTY_PAGE); + + response = await page.goForward(); + expect(response.ok).toBe(true); + expect(response.url).toContain('/grid.html'); + + response = await page.goForward(); + expect(response).toBe(null); + })); + }); + describe('Page.setInPageCallback', function() { it('should work', SX(async function() { await page.setInPageCallback('callController', function(a, b) {