Change Page.navigate to return main resource response
This patch changes Page.navigate API: - Page.navigate now resolves to the main page response - Page.navigate throws errors if there's no main page response, e.g. in case of SSL errors, max navigation timeout, or invalid url. This patch also adds httpsServer with a self-signed certificates for the testing purposes. Fixes #10.
This commit is contained in:
parent
a7e91dc126
commit
50d9c186b5
20
docs/api.md
20
docs/api.md
@ -21,7 +21,7 @@
|
|||||||
* [page.httpHeaders()](#pagehttpheaders)
|
* [page.httpHeaders()](#pagehttpheaders)
|
||||||
* [page.injectFile(filePath)](#pageinjectfilefilepath)
|
* [page.injectFile(filePath)](#pageinjectfilefilepath)
|
||||||
* [page.mainFrame()](#pagemainframe)
|
* [page.mainFrame()](#pagemainframe)
|
||||||
* [page.navigate(url)](#pagenavigateurl)
|
* [page.navigate(url, options)](#pagenavigateurl-options)
|
||||||
* [page.plainText()](#pageplaintext)
|
* [page.plainText()](#pageplaintext)
|
||||||
* [page.printToPDF(filePath[, options])](#pageprinttopdffilepath-options)
|
* [page.printToPDF(filePath[, options])](#pageprinttopdffilepath-options)
|
||||||
* [page.screenshot([options])](#pagescreenshotoptions)
|
* [page.screenshot([options])](#pagescreenshotoptions)
|
||||||
@ -162,12 +162,22 @@ Pages could be closed by `page.close()` method.
|
|||||||
|
|
||||||
#### page.mainFrame()
|
#### page.mainFrame()
|
||||||
|
|
||||||
#### page.navigate(url)
|
#### page.navigate(url, options)
|
||||||
|
|
||||||
- `url` <[string]> URL to navigate page to
|
- `url` <[string]> URL to navigate page to
|
||||||
- returns: <[Promise]<[boolean]>> Promise which resolves when the page is navigated. The promise resolves to:
|
- `options` <[Object]> Navigation parameters which might have the following properties:
|
||||||
- `true` if the navigation succeeds and page's `load` event is fired.
|
- `maxTime` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds.
|
||||||
- `false` if the navigation fails due to bad URL or SSL errors.
|
- `waitFor` <[string]> When to consider navigation succeeded, defaults to `load`. Could be either:
|
||||||
|
- `load` - consider navigation to be finished when the `load` event is fired.
|
||||||
|
- `networkidle` - consider navigation to be finished when the network activity stays "idle" for at least `networkIdleTimeout`ms.
|
||||||
|
- `networkIdleInflight` <[number]> Maximum amount of inflight requests which are considered "idle". Takes effect only with `waitFor: 'networkidle'` parameter.
|
||||||
|
- `networkIdleTimeout` <[number]> A timeout to wait before completing navigation. Takes effect only with `waitFor: 'networkidle'` parameter.
|
||||||
|
- 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.
|
||||||
|
|
||||||
|
The `page.navigate` will throw an error if:
|
||||||
|
- there's an SSL error (e.g. in case of self-signed certificates).
|
||||||
|
- target URL is invalid.
|
||||||
|
- the `maxTime` is exceeded during navigation.
|
||||||
|
|
||||||
#### page.plainText()
|
#### page.plainText()
|
||||||
|
|
||||||
|
@ -34,26 +34,28 @@ class Navigator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {!Promise<boolean>}
|
* @return {!Promise}
|
||||||
*/
|
*/
|
||||||
async navigate() {
|
async navigate() {
|
||||||
this._init();
|
this._init();
|
||||||
let certificateError = new Promise(fulfill => this._client.once('Security.certificateError', fulfill)).then(() => false);
|
let certificateError = new Promise(fulfill => this._client.once('Security.certificateError', fulfill))
|
||||||
let networkIdle = new Promise(fulfill => this._networkIdleCallback = fulfill).then(() => true);
|
.then(error => new Error('SSL Certiciate error: ' + error.errorType));
|
||||||
let loadEventFired = new Promise(fulfill => this._client.once('Page.loadEventFired', fulfill)).then(() => true);
|
let networkIdle = new Promise(fulfill => this._networkIdleCallback = fulfill).then(() => null);
|
||||||
let watchdog = new Promise(fulfill => this._maximumTimer = setTimeout(fulfill, this._maxTime)).then(() => false);
|
let loadEventFired = new Promise(fulfill => this._client.once('Page.loadEventFired', fulfill)).then(() => null);
|
||||||
|
let watchdog = new Promise(fulfill => this._maximumTimer = setTimeout(fulfill, this._maxTime)).then(() => new Error('Navigation Timeout Exceeded: ' + this._maxTime + 'ms exceeded'));
|
||||||
|
|
||||||
// Await for the command to throw exception in case of illegal arguments.
|
// Await for the command to throw exception in case of illegal arguments.
|
||||||
try {
|
try {
|
||||||
await this._client.send('Page.navigate', {url: this._url, referrer: this._referrer});
|
await this._client.send('Page.navigate', {url: this._url, referrer: this._referrer});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this._cleanup();
|
this._cleanup();
|
||||||
return false;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = await Promise.race([certificateError, watchdog, this._waitFor === 'load' ? loadEventFired : networkIdle]);
|
const error = await Promise.race([certificateError, watchdog, this._waitFor === 'load' ? loadEventFired : networkIdle]);
|
||||||
this._cleanup();
|
this._cleanup();
|
||||||
return result;
|
if (error)
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
22
lib/Page.js
22
lib/Page.js
@ -260,10 +260,26 @@ class Page extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* @param {string} html
|
* @param {string} html
|
||||||
* @param {!Object=} options
|
* @param {!Object=} options
|
||||||
* @return {!Promise<boolean>}
|
* @return {!Promise<!Response>}
|
||||||
*/
|
*/
|
||||||
navigate(url, options) {
|
async navigate(url, options) {
|
||||||
return new Navigator(this._client, url, this._networkManager.httpHeaders().referer, options).navigate();
|
/** @type {!Map<string, !Response>} */
|
||||||
|
const responses = new Map();
|
||||||
|
const onResponse = response => responses.set(response.url, response);
|
||||||
|
const navigator = new Navigator(this._client, url, this._networkManager.httpHeaders().referer, options);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this._networkManager.on(NetworkManager.Events.Response, onResponse);
|
||||||
|
await navigator.navigate();
|
||||||
|
} catch (e) {
|
||||||
|
this._networkManager.removeListener(NetworkManager.Events.Response, onResponse);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._networkManager.removeListener(NetworkManager.Events.Response, onResponse);
|
||||||
|
const response = responses.get(this.mainFrame().url());
|
||||||
|
console.assert(response);
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -355,22 +355,25 @@ class WebPage {
|
|||||||
this._deferEvaluate = false;
|
this._deferEvaluate = false;
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.loadingProgress = 50;
|
this.loadingProgress = 50;
|
||||||
this._page.navigate(url).then(result => {
|
|
||||||
|
const handleNavigation = (error, response) => {
|
||||||
this.loadingProgress = 100;
|
this.loadingProgress = 100;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
let status = result ? 'success' : 'fail';
|
if (error) {
|
||||||
if (!result) {
|
|
||||||
this.onResourceError.call(null, {
|
this.onResourceError.call(null, {
|
||||||
url,
|
url,
|
||||||
errorString: 'SSL handshake failed'
|
errorString: 'SSL handshake failed'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
let status = error ? 'fail' : 'success';
|
||||||
if (this.onLoadFinished)
|
if (this.onLoadFinished)
|
||||||
this.onLoadFinished.call(null, status);
|
this.onLoadFinished.call(null, status);
|
||||||
if (callback)
|
if (callback)
|
||||||
callback.call(null, status);
|
callback.call(null, status);
|
||||||
this.loadingProgress = 0;
|
this.loadingProgress = 0;
|
||||||
});
|
};
|
||||||
|
this._page.navigate(url).then(response => handleNavigation(null, response))
|
||||||
|
.catch(e => handleNavigation(e, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
let http = require('http');
|
let http = require('http');
|
||||||
|
let https = require('https');
|
||||||
let url = require('url');
|
let url = require('url');
|
||||||
let fs = require('fs');
|
let fs = require('fs');
|
||||||
let path = require('path');
|
let path = require('path');
|
||||||
@ -39,8 +40,27 @@ class SimpleServer {
|
|||||||
/**
|
/**
|
||||||
* @param {string} dirPath
|
* @param {string} dirPath
|
||||||
* @param {number} port
|
* @param {number} port
|
||||||
|
* @return {!SimpleServer}
|
||||||
*/
|
*/
|
||||||
constructor(dirPath, port) {
|
static async createHTTPS(dirPath, port) {
|
||||||
|
let server = new SimpleServer(dirPath, port, {
|
||||||
|
key: fs.readFileSync(path.join(__dirname, 'key.pem')),
|
||||||
|
cert: fs.readFileSync(path.join(__dirname, 'cert.pem')),
|
||||||
|
passphrase: 'aaaa',
|
||||||
|
});
|
||||||
|
await new Promise(x => server._server.once('listening', x));
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} dirPath
|
||||||
|
* @param {number} port
|
||||||
|
* @param {!Object=} sslOptions
|
||||||
|
*/
|
||||||
|
constructor(dirPath, port, sslOptions) {
|
||||||
|
if (sslOptions)
|
||||||
|
this._server = https.createServer(sslOptions, this._onRequest.bind(this));
|
||||||
|
else
|
||||||
this._server = http.createServer(this._onRequest.bind(this));
|
this._server = http.createServer(this._onRequest.bind(this));
|
||||||
this._server.on('connection', socket => this._onSocket(socket));
|
this._server.on('connection', socket => this._onSocket(socket));
|
||||||
this._wsServer = new WebSocketServer({server: this._server});
|
this._wsServer = new WebSocketServer({server: this._server});
|
31
test/server/cert.pem
Normal file
31
test/server/cert.pem
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIFXzCCA0egAwIBAgIJAM+8uXXn61zZMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
||||||
|
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||||
|
aWRnaXRzIFB0eSBMdGQwIBcNMTcwNzEwMjI1MDA2WhgPMzAxNjExMTAyMjUwMDZa
|
||||||
|
MEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJ
|
||||||
|
bnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
||||||
|
ggIKAoICAQCfsIbw1Q91wooUdSu5tDiyrSYB6ZQmY49Y141KQ0ll0ZXzf1sPTpPg
|
||||||
|
OuBjJE8Fre2Wn3jJ0SfLFyQBMvE49hqWyY/U5Xc367ujqKFQVoItnoV5MM2TPu5J
|
||||||
|
/zhtf26Vq0Pcrujt5LfRe1JSYKdJ21Tquqa0MAGI0HghaCdSdtyo2xuotnukirKb
|
||||||
|
QrvP/YNa+ONZT6KW8MFAwfoCOJMo1idrkBA1Wve5xcCd7J9Oy5mWCBxTSR67W2vQ
|
||||||
|
izoOTSkzD0xoXpFF5V/34zJGWU9t6Z5qytV/w5ROY3Tk9EaKs0NcQmXlCxSmkXil
|
||||||
|
KSTlZ/VDeDliI92jGn4hT+apisglm3aaTnVVAP0EbZ/CF9Fwb601M7IcAP9ejaeB
|
||||||
|
EEs+smXpuzhAfxPa5SpZCWeaXLcFq6Ewi2LXrMaChWvbu9AUi3QjuT3u9PW3B0w5
|
||||||
|
C54FLfvcy9X9dQQ/jCgydF3eyhiO3SuLZqrhofHUn53z4UCEYgbC7uQSv08ep2UD
|
||||||
|
kT2ARN6aetXVgiQBYS8hcGaFrdsUTSAmT0flt0g8ZoHn+NmuAWxbAx8UnPd0p/EP
|
||||||
|
B4cZByDOUDGgDMSOEluheiCFlZBQEJnvOhim6rwSje87EzQazGkwRpOrBtzGIGcM
|
||||||
|
xmotG9IrMbzKb4Z+yg5pOEW2WKEy3f2h8P2bisbbHwYa/tgTHVWbGwIDAQABo1Aw
|
||||||
|
TjAdBgNVHQ4EFgQUZvIOJVkyQTAd0fpUkpqgcXVID+4wHwYDVR0jBBgwFoAUZvIO
|
||||||
|
JVkyQTAd0fpUkpqgcXVID+4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
|
||||||
|
AgEASmqzfr4TOVFbNo3r85QlCQB8W4xaArRpY6k7ugxJm2/9iyyovMKMhCcRvmPV
|
||||||
|
HZXDTV8WEbLDg3uNF56WU39YmtfjghnsYcGQ/UhnH2PoHQxGIKzOoalLew7kP0Uc
|
||||||
|
HCmXi7OPjqeFQgjWVhLkL/RIzZ3vOVFQfqodTVIdYDe0O1cNRD0U0rtGa0MHzZlD
|
||||||
|
y/ZaksiB0E3UL/GsgyJoCxCAF1E80PU9aw1K9COyTOChpUKnhSHC964KlhnJKyOe
|
||||||
|
HKCYtb5RVrF7ryBcGneLTcQm/oNUp8aRyiwyQIDH7djFSp11MakXBF+EeGR523pp
|
||||||
|
u+sleR7ZFBGyb3Z5K9NdRdUk0SWu7Hu4jQtJHn+PmIZ1qjfbPv5qDfVd1vmFwqsu
|
||||||
|
7NfsLoNm0dQNu5WOMLISQHmQiT86AH2wWQ3l5Sm+g8/BdNLQLklhtZcRhp2efyiL
|
||||||
|
ciUmGugKqoX+nPIZ36kuoRTZy++AnTiid011vZFe1qrfug/ykWiqWmBSvD/cfRU4
|
||||||
|
ydoK87cfjIixqmpRZ7j2q+/cDK2SbYN0t/Xrufw3L6TjDgUEL7ZCImcwqqWJz9I8
|
||||||
|
ASnnL5PhX8bbsUrtE21Ugqk2zYnVnqRO5FjINtlTb07y9pGC/QpBkb1AasF5okhe
|
||||||
|
7lw/sMiryKKzS4A10nRV/+gErDBsIBj+cpGPM8brLfZuy2o=
|
||||||
|
-----END CERTIFICATE-----
|
54
test/server/key.pem
Normal file
54
test/server/key.pem
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||||
|
MIIJjjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIT2qHBljWwsICAggA
|
||||||
|
MBQGCCqGSIb3DQMHBAh5lMoGsb1UgQSCCUg/FtxOBSUG05DteTzzkdp6FptfOy5p
|
||||||
|
iirYKWUNck6EhPdZ1RPSuCvs84S+qP6Po5gFfGz9e7tdbNSueOQnMD+vbS8vXpZU
|
||||||
|
4KVafxUlKbAfSVj2ZY6SkbU8v/iXiTieUj3G046z5QYsfcvyEdS47Z+WbKAJKemv
|
||||||
|
BVck4W+/gKtiukbK/94VaehC7kbbO2yp9/kYp9qqk33aB61C8xX/fILOIRdYkvut
|
||||||
|
55pHGviN5Eajabm/d83MPAzaqUdv9NiIKej2IFXs+Oz8OYRbVVHwyN93HquHmn+V
|
||||||
|
WKOknJXzvS5Pa+ViGmB4o6+fpluuIyHXJUUG20z/IY5n0vaBo4jRlyYZ3J1vWTZ2
|
||||||
|
1bhLGPUPUlGt1vToY5Ejr8qxaYGxLEOOxvRL3Z1xnlCbv2tQTD3TyV+Yr7i/54s4
|
||||||
|
2h0ddnP22KDmKEA8PhxZMZG7i7fsO+yA6hbKeMnS8lGv5Yyw2H7vRm4JwgeuX7A7
|
||||||
|
gPQ/zQ6Sf6fUCkOMgVD3jJZ4XK7l9GkEQMYJAoowYb+WJ+yHSUQWJLJzPnNqhAPT
|
||||||
|
aqQGHAO+AjGDnSI6ANDlxUubfU4yjQPg2eVyFczS7G+BISgCrJyQP/Z3Mpzo5rdu
|
||||||
|
iTVcH8Phvsdm3PBOTkbgqxeHos6tyIiH1aElwlG3hxM1QiM6D9p7b5RyjUqfP/qn
|
||||||
|
r1CndzroAyvseQ3ET8mJQAqWdGd+qmw9t0Voi7sR9jcDLVw+oLSk+oD8dk6BrItI
|
||||||
|
rb39DmQAJiP7sLtAZ/zUm3sRpGgytNjElzzDdmijCM1A5oJzLvRwwa4AHwicMBkW
|
||||||
|
nRnvliockHhFHQnQ/QThNGTPoNOHHgWwUKIidSFAdPIK1tYJP/4te2t5Djm25jS7
|
||||||
|
ITm/LR1gbUguOMlOqwrDyAQir5Jjjk2pqN30+W9AXgVk/Oq/bWC8eMRv8zsmBlUY
|
||||||
|
poXBwV52ITCzpNOsywSpz1vWGs1I0WQcLbm1zrHCR3CYxPOB45XdvHtwnHn5zaLF
|
||||||
|
NB42IS/zK4PYzSJrbwJMsILS51Qb88JNL4PvYMCz43dUd0W6hokX4yCnQjfeEvB1
|
||||||
|
MIhYQBu/lFK3IsskgoYBeg4zbU950vKSL+oNb5/dzAoayyJ/jRg5a1xMx8tCHazW
|
||||||
|
5afYxyIE9FRThwsHQ7K8BGe/4qwMCbvDIh/Fk+tWqXiyJJdsixf6YZLXtQXPkzki
|
||||||
|
azpN9plUSoWpTVY4i6wNF5IO5LExLWlemDnw1v99lnU5W3SfgEwV8DYAyScA7Qzd
|
||||||
|
GJQEfZVPSSxMQSyfrAap80PVs5KZWYcJpzKl9vwwdzopA2oj2vvx40r43YFiVFHp
|
||||||
|
IpG9biWgh6McKKVCT1QThtNktDS9NT4uQZofC6m+RzzbsfI2R9IelozSOrS3xRJd
|
||||||
|
D1eTiIccuomOsrhnh+/VDc9iuP6LgGaKwjdNSfcryuOn3S2+vho7wGrul/GxRf5k
|
||||||
|
GrT1C68y5e0C/qbxyKtJPEGcntgLADhVrPr3WiM2M4tZ/imMi9XeyKSZ3i6P0OB/
|
||||||
|
QkhfNLrws03nXi3ASpk7/C9EWnnAYGwxQRht2LpEcTOpCUmmZ+6cBM4+dXMjvxqU
|
||||||
|
SXR93Vm7Rwfs3MSIbtD2lGEXaIvG5mOh/9HXByBOh/UuSATeUIgEWgfW1zn0tvAw
|
||||||
|
muqOyeS+ngYtoRK0NV979Kp7Pizq7ZHpoemm+C65EVvq2CU/ceRNh6DwCW5ZCHvU
|
||||||
|
rJdOXqdO9Oef/2rHmLjnkwIjkXS3MJFd9wlCsSJn2SsuNmSLkwXuEkgdbjMKwjW+
|
||||||
|
sKzozd6FDp80HBuNw6H+kBn8KhO9tdQmyZnS9EpwO+OLgCTuyDNBiA892aevx9zD
|
||||||
|
7WPzNlsppcMEcxudv0mvavMfUJhbQ0wo+9Rp3wRQXIquKt++5vK7EoPvUjhVO39p
|
||||||
|
1VJTfx/wnX39VF62hc+OH3rritHmsrCBwzPupDGWSLBwQcMJbmgjFojuMG02pkIM
|
||||||
|
mR5HIp+Xl4fWmSa9aklVyssdSi1hK+6VRIafTPtCiyA2BfeeYQk1xEsjSai0TYqh
|
||||||
|
Suw+3wKOORm0xPEV30qX08N3bCP7aqqA+dMXWjfDM7LUBzDV4+MX6WOMdunlBdIS
|
||||||
|
6q63DXon6CCLoXPun/IwUEhOZfh43UAF3qEfxJdkhH6AgPdCSYBB5AWHQDdqvrBY
|
||||||
|
wkhPEXkY2viMF2hOknXQr1GAdx0EjnAaMMxDE7+q01ERdgnO0xRVOD/4DjngdU4K
|
||||||
|
p935fERs5/1nWe4yq/z8lXEC2W3YdiPR3Ok+pekyzhokh5/b+eG8G0JEnnl4+M8y
|
||||||
|
qqyZZTJJeDFhasOzxwc5hwq8yqOznF6dEF58FXO9pKqBXbz5NrwbdUPtp67WwNx7
|
||||||
|
iTRNe9szns5U8/3S5LEg+xGvAUhwbdmWxzYHye2MAt4sObi4YFDb1RVkZzCj2eer
|
||||||
|
6hzCQi5VUB3pUqr8in1TJMXPzCrl4ZdK2KoHtNA1gKT7midLzsjP+rXsgKtzcGAO
|
||||||
|
IcNOkbv8KqzYr2OtcEW+v9z6vgSpKImQ/n+6/WLRGWh9pLCZ+onD06OLcsm55H4y
|
||||||
|
zNacau+nT+Mf9XQTErFjj2+orjF3p2u3tY9vpoLJN653mMTNzexVZi+k9NgZz7eL
|
||||||
|
4m8R3ai0ZeGQezo9rGHQ6ulqlueN0qXGKI07G4VKxM35OZeOyPPnrF95FQzMY5Ox
|
||||||
|
GkQr1hR0rj+oQJTFWIfy9ffZEBzUqC8fYYvOPJO32I+fe2tvBUtpUe3w7dYHVs3a
|
||||||
|
lqi/+Wwk0QLE4ItR5f0sZsoIeHkDeXoKYrCOOPl2bnIQA3UT/rszGl6YDY8pU/7W
|
||||||
|
fziO/G5BzGe7LU7o26ykzkmDF5alUaNdfVnnQcm/iRy8YOsjfKQmqbFfFCKOlRMo
|
||||||
|
RdTStOcsEzddttI57YlBHv5Gh1GfMjd5acgeQfStSMwHcahwY2Y36WcR4GE4Id/5
|
||||||
|
ycaikCt+zYEVKUoO+JEZxvzFQIPVhT3oBOjSFj/EeMLmnGMjnohdgEmh2T7+0Ko5
|
||||||
|
oAMzWW/XNeJlL1DAPPEpya66oSvwZvxUkGDLcIGYWgzSKz0JO8zn6wDTOU7O2YeF
|
||||||
|
Gm8YymS0oqnK1wE6HJ1YSk2ers6kgZij3kVAnGlbI88YLeMJvteO2oL7GqfEQdSA
|
||||||
|
HskQklLZUT2Y+m7oinVyCcdbKRGI9frnfm6j3TVkrNHjcc7aKhM+XT5ZNKxT3ftt
|
||||||
|
4Ig=
|
||||||
|
-----END ENCRYPTED PRIVATE KEY-----
|
135
test/test.js
135
test/test.js
@ -17,12 +17,14 @@
|
|||||||
let fs = require('fs');
|
let fs = require('fs');
|
||||||
let path = require('path');
|
let path = require('path');
|
||||||
let Browser = require('../lib/Browser');
|
let Browser = require('../lib/Browser');
|
||||||
let SimpleServer = require('./SimpleServer');
|
let SimpleServer = require('./server/SimpleServer');
|
||||||
let GoldenUtils = require('./golden-utils');
|
let GoldenUtils = require('./golden-utils');
|
||||||
|
|
||||||
let PORT = 8907;
|
let PORT = 8907;
|
||||||
let STATIC_PREFIX = 'http://localhost:' + PORT;
|
let PREFIX = 'http://localhost:' + PORT;
|
||||||
let EMPTY_PAGE = STATIC_PREFIX + '/empty.html';
|
let EMPTY_PAGE = PREFIX + '/empty.html';
|
||||||
|
let HTTPS_PORT = 8908;
|
||||||
|
let HTTPS_PREFIX = 'https://localhost:' + HTTPS_PORT;
|
||||||
|
|
||||||
if (process.env.DEBUG_TEST)
|
if (process.env.DEBUG_TEST)
|
||||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 1000 * 1000;
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 1000 * 1000;
|
||||||
@ -32,22 +34,29 @@ else
|
|||||||
describe('Puppeteer', function() {
|
describe('Puppeteer', function() {
|
||||||
let browser;
|
let browser;
|
||||||
let server;
|
let server;
|
||||||
|
let httpsServer;
|
||||||
let page;
|
let page;
|
||||||
|
|
||||||
beforeAll(SX(async function() {
|
beforeAll(SX(async function() {
|
||||||
browser = new Browser({args: ['--no-sandbox']});
|
browser = new Browser({args: ['--no-sandbox']});
|
||||||
server = await SimpleServer.create(path.join(__dirname, 'assets'), PORT);
|
const assetsPath = path.join(__dirname, 'assets');
|
||||||
|
server = await SimpleServer.create(assetsPath, PORT);
|
||||||
|
httpsServer = await SimpleServer.createHTTPS(assetsPath, HTTPS_PORT);
|
||||||
GoldenUtils.removeOutputDir();
|
GoldenUtils.removeOutputDir();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
afterAll(SX(async function() {
|
afterAll(SX(async function() {
|
||||||
await server.stop();
|
await Promise.all([
|
||||||
|
server.stop(),
|
||||||
|
httpsServer.stop(),
|
||||||
|
]);
|
||||||
browser.close();
|
browser.close();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(SX(async function() {
|
beforeEach(SX(async function() {
|
||||||
page = await browser.newPage();
|
page = await browser.newPage();
|
||||||
server.reset();
|
server.reset();
|
||||||
|
httpsServer.reset();
|
||||||
GoldenUtils.addMatchers(jasmine);
|
GoldenUtils.addMatchers(jasmine);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -186,12 +195,54 @@ describe('Puppeteer', function() {
|
|||||||
|
|
||||||
describe('Page.navigate', function() {
|
describe('Page.navigate', function() {
|
||||||
it('should fail when navigating to bad url', SX(async function() {
|
it('should fail when navigating to bad url', SX(async function() {
|
||||||
let success = await page.navigate('asdfasdf');
|
let error = null;
|
||||||
expect(success).toBe(false);
|
try {
|
||||||
|
await page.navigate('asdfasdf');
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
expect(error.message).toContain('Cannot navigate to invalid URL');
|
||||||
}));
|
}));
|
||||||
it('should succeed when navigating to good url', SX(async function() {
|
it('should fail when navigating to bad SSL', SX(async function() {
|
||||||
let success = await page.navigate(EMPTY_PAGE);
|
let error = null;
|
||||||
expect(success).toBe(true);
|
try {
|
||||||
|
await page.navigate(HTTPS_PREFIX + '/empty.html');
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
expect(error.message).toContain('SSL Certiciate error');
|
||||||
|
}));
|
||||||
|
it('should fail when exceeding maximum navigation timeout', SX(async function() {
|
||||||
|
let error = null;
|
||||||
|
// Hang for request to the empty.html
|
||||||
|
server.setRoute('/empty.html', (req, res) => { });
|
||||||
|
try {
|
||||||
|
await page.navigate(PREFIX + '/empty.html', {maxTime: 59});
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
expect(error.message).toContain('Navigation Timeout Exceeded: 59ms');
|
||||||
|
}));
|
||||||
|
it('should work when navigating to valid url', SX(async function() {
|
||||||
|
const response = await page.navigate(EMPTY_PAGE);
|
||||||
|
expect(response.ok).toBe(true);
|
||||||
|
}));
|
||||||
|
it('should work when navigating to data url', SX(async function() {
|
||||||
|
const response = await page.navigate('data:text/html,hello');
|
||||||
|
expect(response.ok).toBe(true);
|
||||||
|
}));
|
||||||
|
it('should work when navigating to 404', SX(async function() {
|
||||||
|
const response = await page.navigate(PREFIX + '/not-found');
|
||||||
|
expect(response.ok).toBe(false);
|
||||||
|
expect(response.status).toBe(404);
|
||||||
|
}));
|
||||||
|
it('should return last response in redirect chain', SX(async function() {
|
||||||
|
server.setRedirect('/redirect/1.html', '/redirect/2.html');
|
||||||
|
server.setRedirect('/redirect/2.html', '/redirect/3.html');
|
||||||
|
server.setRedirect('/redirect/3.html', EMPTY_PAGE);
|
||||||
|
const response = await page.navigate(PREFIX + '/redirect/1.html');
|
||||||
|
expect(response.ok).toBe(true);
|
||||||
|
expect(response.url).toBe(EMPTY_PAGE);
|
||||||
}));
|
}));
|
||||||
it('should wait for network idle to succeed navigation', SX(async function() {
|
it('should wait for network idle to succeed navigation', SX(async function() {
|
||||||
let responses = [];
|
let responses = [];
|
||||||
@ -209,7 +260,7 @@ describe('Puppeteer', function() {
|
|||||||
|
|
||||||
// Navigate to a page which loads immediately and then does a bunch of
|
// Navigate to a page which loads immediately and then does a bunch of
|
||||||
// requests via javascript's fetch method.
|
// requests via javascript's fetch method.
|
||||||
let navigationPromise = page.navigate(STATIC_PREFIX + '/networkidle.html', {
|
let navigationPromise = page.navigate(PREFIX + '/networkidle.html', {
|
||||||
waitFor: 'networkidle',
|
waitFor: 'networkidle',
|
||||||
networkIdleTimeout: 100,
|
networkIdleTimeout: 100,
|
||||||
networkIdleInflight: 0, // Only be idle when there are 0 inflight requests
|
networkIdleInflight: 0, // Only be idle when there are 0 inflight requests
|
||||||
@ -248,9 +299,9 @@ describe('Puppeteer', function() {
|
|||||||
response.end(`File not found`);
|
response.end(`File not found`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let success = await navigationPromise;
|
const response = await navigationPromise;
|
||||||
// Expect navigation to succeed.
|
// Expect navigation to succeed.
|
||||||
expect(success).toBe(true);
|
expect(response.ok).toBe(true);
|
||||||
}));
|
}));
|
||||||
it('should wait for websockets to succeed navigation', SX(async function() {
|
it('should wait for websockets to succeed navigation', SX(async function() {
|
||||||
let responses = [];
|
let responses = [];
|
||||||
@ -259,7 +310,7 @@ describe('Puppeteer', function() {
|
|||||||
let fetchResourceRequested = server.waitForRequest('/fetch-request.js');
|
let fetchResourceRequested = server.waitForRequest('/fetch-request.js');
|
||||||
// Navigate to a page which loads immediately and then opens a bunch of
|
// Navigate to a page which loads immediately and then opens a bunch of
|
||||||
// websocket connections and then a fetch request.
|
// websocket connections and then a fetch request.
|
||||||
let navigationPromise = page.navigate(STATIC_PREFIX + '/websocket.html', {
|
let navigationPromise = page.navigate(PREFIX + '/websocket.html', {
|
||||||
waitFor: 'networkidle',
|
waitFor: 'networkidle',
|
||||||
networkIdleTimeout: 100,
|
networkIdleTimeout: 100,
|
||||||
networkIdleInflight: 0, // Only be idle when there are 0 inflight requests/connections
|
networkIdleInflight: 0, // Only be idle when there are 0 inflight requests/connections
|
||||||
@ -283,9 +334,9 @@ describe('Puppeteer', function() {
|
|||||||
response.statusCode = 404;
|
response.statusCode = 404;
|
||||||
response.end(`File not found`);
|
response.end(`File not found`);
|
||||||
}
|
}
|
||||||
let success = await navigationPromise;
|
const response = await navigationPromise;
|
||||||
// Expect navigation to succeed.
|
// Expect navigation to succeed.
|
||||||
expect(success).toBe(true);
|
expect(response.ok).toBe(true);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -331,8 +382,8 @@ describe('Puppeteer', function() {
|
|||||||
expect(request.postData).toBe(undefined);
|
expect(request.postData).toBe(undefined);
|
||||||
request.continue();
|
request.continue();
|
||||||
});
|
});
|
||||||
let success = await page.navigate(EMPTY_PAGE);
|
const response = await page.navigate(EMPTY_PAGE);
|
||||||
expect(success).toBe(true);
|
expect(response.ok).toBe(true);
|
||||||
}));
|
}));
|
||||||
it('should show custom HTTP headers', SX(async function() {
|
it('should show custom HTTP headers', SX(async function() {
|
||||||
await page.setHTTPHeaders({
|
await page.setHTTPHeaders({
|
||||||
@ -342,8 +393,8 @@ describe('Puppeteer', function() {
|
|||||||
expect(request.headers.get('foo')).toBe('bar');
|
expect(request.headers.get('foo')).toBe('bar');
|
||||||
request.continue();
|
request.continue();
|
||||||
});
|
});
|
||||||
let success = await page.navigate(EMPTY_PAGE);
|
const response = await page.navigate(EMPTY_PAGE);
|
||||||
expect(success).toBe(true);
|
expect(response.ok).toBe(true);
|
||||||
}));
|
}));
|
||||||
it('should be abortable', SX(async function() {
|
it('should be abortable', SX(async function() {
|
||||||
page.setRequestInterceptor(request => {
|
page.setRequestInterceptor(request => {
|
||||||
@ -354,8 +405,8 @@ describe('Puppeteer', function() {
|
|||||||
});
|
});
|
||||||
let failedRequests = 0;
|
let failedRequests = 0;
|
||||||
page.on('requestfailed', event => ++failedRequests);
|
page.on('requestfailed', event => ++failedRequests);
|
||||||
let success = await page.navigate(STATIC_PREFIX + '/one-style.html');
|
const response = await page.navigate(PREFIX + '/one-style.html');
|
||||||
expect(success).toBe(true);
|
expect(response.ok).toBe(true);
|
||||||
expect(failedRequests).toBe(1);
|
expect(failedRequests).toBe(1);
|
||||||
}));
|
}));
|
||||||
it('should amend HTTP headers', SX(async function() {
|
it('should amend HTTP headers', SX(async function() {
|
||||||
@ -400,7 +451,7 @@ describe('Puppeteer', function() {
|
|||||||
expect(error.message).toContain('Fancy');
|
expect(error.message).toContain('Fancy');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
page.navigate(STATIC_PREFIX + '/error.html');
|
page.navigate(PREFIX + '/error.html');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -417,13 +468,13 @@ describe('Puppeteer', function() {
|
|||||||
describe('Page.screenshot', function() {
|
describe('Page.screenshot', function() {
|
||||||
it('should work', SX(async function() {
|
it('should work', SX(async function() {
|
||||||
await page.setViewportSize({width: 500, height: 500});
|
await page.setViewportSize({width: 500, height: 500});
|
||||||
await page.navigate(STATIC_PREFIX + '/grid.html');
|
await page.navigate(PREFIX + '/grid.html');
|
||||||
let screenshot = await page.screenshot();
|
let screenshot = await page.screenshot();
|
||||||
expect(screenshot).toBeGolden('screenshot-sanity.png');
|
expect(screenshot).toBeGolden('screenshot-sanity.png');
|
||||||
}));
|
}));
|
||||||
it('should clip rect', SX(async function() {
|
it('should clip rect', SX(async function() {
|
||||||
await page.setViewportSize({width: 500, height: 500});
|
await page.setViewportSize({width: 500, height: 500});
|
||||||
await page.navigate(STATIC_PREFIX + '/grid.html');
|
await page.navigate(PREFIX + '/grid.html');
|
||||||
let screenshot = await page.screenshot({
|
let screenshot = await page.screenshot({
|
||||||
clip: {
|
clip: {
|
||||||
x: 50,
|
x: 50,
|
||||||
@ -436,7 +487,7 @@ describe('Puppeteer', function() {
|
|||||||
}));
|
}));
|
||||||
it('should work for offscreen clip', SX(async function() {
|
it('should work for offscreen clip', SX(async function() {
|
||||||
await page.setViewportSize({width: 500, height: 500});
|
await page.setViewportSize({width: 500, height: 500});
|
||||||
await page.navigate(STATIC_PREFIX + '/grid.html');
|
await page.navigate(PREFIX + '/grid.html');
|
||||||
let screenshot = await page.screenshot({
|
let screenshot = await page.screenshot({
|
||||||
clip: {
|
clip: {
|
||||||
x: 50,
|
x: 50,
|
||||||
@ -449,7 +500,7 @@ describe('Puppeteer', function() {
|
|||||||
}));
|
}));
|
||||||
it('should run in parallel', SX(async function() {
|
it('should run in parallel', SX(async function() {
|
||||||
await page.setViewportSize({width: 500, height: 500});
|
await page.setViewportSize({width: 500, height: 500});
|
||||||
await page.navigate(STATIC_PREFIX + '/grid.html');
|
await page.navigate(PREFIX + '/grid.html');
|
||||||
let promises = [];
|
let promises = [];
|
||||||
for (let i = 0; i < 3; ++i) {
|
for (let i = 0; i < 3; ++i) {
|
||||||
promises.push(page.screenshot({
|
promises.push(page.screenshot({
|
||||||
@ -466,7 +517,7 @@ describe('Puppeteer', function() {
|
|||||||
}));
|
}));
|
||||||
it('should take fullPage screenshots', SX(async function() {
|
it('should take fullPage screenshots', SX(async function() {
|
||||||
await page.setViewportSize({width: 500, height: 500});
|
await page.setViewportSize({width: 500, height: 500});
|
||||||
await page.navigate(STATIC_PREFIX + '/grid.html');
|
await page.navigate(PREFIX + '/grid.html');
|
||||||
let screenshot = await page.screenshot({
|
let screenshot = await page.screenshot({
|
||||||
fullPage: true
|
fullPage: true
|
||||||
});
|
});
|
||||||
@ -477,7 +528,7 @@ describe('Puppeteer', function() {
|
|||||||
describe('Frame Management', function() {
|
describe('Frame Management', function() {
|
||||||
let FrameUtils = require('./frame-utils');
|
let FrameUtils = require('./frame-utils');
|
||||||
it('should handle nested frames', SX(async function() {
|
it('should handle nested frames', SX(async function() {
|
||||||
await page.navigate(STATIC_PREFIX + '/frames/nested-frames.html');
|
await page.navigate(PREFIX + '/frames/nested-frames.html');
|
||||||
expect(FrameUtils.dumpFrames(page.mainFrame())).toBeGolden('nested-frames.txt');
|
expect(FrameUtils.dumpFrames(page.mainFrame())).toBeGolden('nested-frames.txt');
|
||||||
}));
|
}));
|
||||||
it('should send events when frames are manipulated dynamically', SX(async function() {
|
it('should send events when frames are manipulated dynamically', SX(async function() {
|
||||||
@ -523,7 +574,7 @@ describe('Puppeteer', function() {
|
|||||||
page.on('frameattached', frame => attachedFrames.push(frame));
|
page.on('frameattached', frame => attachedFrames.push(frame));
|
||||||
page.on('framedetached', frame => detachedFrames.push(frame));
|
page.on('framedetached', frame => detachedFrames.push(frame));
|
||||||
page.on('framenavigated', frame => navigatedFrames.push(frame));
|
page.on('framenavigated', frame => navigatedFrames.push(frame));
|
||||||
await page.navigate(STATIC_PREFIX + '/frames/nested-frames.html');
|
await page.navigate(PREFIX + '/frames/nested-frames.html');
|
||||||
expect(attachedFrames.length).toBe(4);
|
expect(attachedFrames.length).toBe(4);
|
||||||
expect(detachedFrames.length).toBe(0);
|
expect(detachedFrames.length).toBe(0);
|
||||||
expect(navigatedFrames.length).toBe(5);
|
expect(navigatedFrames.length).toBe(5);
|
||||||
@ -540,12 +591,12 @@ describe('Puppeteer', function() {
|
|||||||
|
|
||||||
describe('input', function() {
|
describe('input', function() {
|
||||||
it('should click the button', SX(async function() {
|
it('should click the button', SX(async function() {
|
||||||
await page.navigate(STATIC_PREFIX + '/input/button.html');
|
await page.navigate(PREFIX + '/input/button.html');
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate(() => result)).toBe('Clicked');
|
||||||
}));
|
}));
|
||||||
it('should fail to click a missing button', SX(async function() {
|
it('should fail to click a missing button', SX(async function() {
|
||||||
await page.navigate(STATIC_PREFIX + '/input/button.html');
|
await page.navigate(PREFIX + '/input/button.html');
|
||||||
try {
|
try {
|
||||||
await page.click('button.does-not-exist');
|
await page.click('button.does-not-exist');
|
||||||
fail('Clicking the button did not throw.');
|
fail('Clicking the button did not throw.');
|
||||||
@ -554,20 +605,20 @@ describe('Puppeteer', function() {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
it('should type into the textarea', SX(async function() {
|
it('should type into the textarea', SX(async function() {
|
||||||
await page.navigate(STATIC_PREFIX + '/input/textarea.html');
|
await page.navigate(PREFIX + '/input/textarea.html');
|
||||||
await page.focus('textarea');
|
await page.focus('textarea');
|
||||||
await page.type('Type in this text!');
|
await page.type('Type in this text!');
|
||||||
expect(await page.evaluate(() => result)).toBe('Type in this text!');
|
expect(await page.evaluate(() => result)).toBe('Type in this text!');
|
||||||
}));
|
}));
|
||||||
it('should click the button after navigation ', SX(async function() {
|
it('should click the button after navigation ', SX(async function() {
|
||||||
await page.navigate(STATIC_PREFIX + '/input/button.html');
|
await page.navigate(PREFIX + '/input/button.html');
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
await page.navigate(STATIC_PREFIX + '/input/button.html');
|
await page.navigate(PREFIX + '/input/button.html');
|
||||||
await page.click('button');
|
await page.click('button');
|
||||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
expect(await page.evaluate(() => result)).toBe('Clicked');
|
||||||
}));
|
}));
|
||||||
it('should upload the file', SX(async function(){
|
it('should upload the file', SX(async function(){
|
||||||
await page.navigate(STATIC_PREFIX + '/input/fileupload.html');
|
await page.navigate(PREFIX + '/input/fileupload.html');
|
||||||
await page.uploadFile('input', __dirname + '/assets/file-to-upload.txt');
|
await page.uploadFile('input', __dirname + '/assets/file-to-upload.txt');
|
||||||
expect(await page.evaluate(() => {
|
expect(await page.evaluate(() => {
|
||||||
let input = document.querySelector('input');
|
let input = document.querySelector('input');
|
||||||
@ -626,7 +677,7 @@ describe('Puppeteer', function() {
|
|||||||
it('should work', SX(async function() {
|
it('should work', SX(async function() {
|
||||||
let response = null;
|
let response = null;
|
||||||
page.on('response', r => response = r);
|
page.on('response', r => response = r);
|
||||||
await page.navigate(STATIC_PREFIX + '/simple.json');
|
await page.navigate(PREFIX + '/simple.json');
|
||||||
expect(response).toBeTruthy();
|
expect(response).toBeTruthy();
|
||||||
expect(response.bodyUsed).toBe(false);
|
expect(response.bodyUsed).toBe(false);
|
||||||
expect(await response.text()).toBe('{"foo": "bar"}\n');
|
expect(await response.text()).toBe('{"foo": "bar"}\n');
|
||||||
@ -663,7 +714,7 @@ describe('Puppeteer', function() {
|
|||||||
});
|
});
|
||||||
let failedRequests = [];
|
let failedRequests = [];
|
||||||
page.on('requestfailed', request => failedRequests.push(request));
|
page.on('requestfailed', request => failedRequests.push(request));
|
||||||
await page.navigate(STATIC_PREFIX + '/one-style.html');
|
await page.navigate(PREFIX + '/one-style.html');
|
||||||
expect(failedRequests.length).toBe(1);
|
expect(failedRequests.length).toBe(1);
|
||||||
expect(failedRequests[0].url).toContain('one-style.css');
|
expect(failedRequests[0].url).toContain('one-style.css');
|
||||||
expect(failedRequests[0].response()).toBe(null);
|
expect(failedRequests[0].response()).toBe(null);
|
||||||
@ -691,7 +742,7 @@ describe('Puppeteer', function() {
|
|||||||
page.on('requestfinished', request => events.push(`DONE ${request.url}`));
|
page.on('requestfinished', request => events.push(`DONE ${request.url}`));
|
||||||
page.on('requestfailed', request => events.push(`FAIL ${request.url}`));
|
page.on('requestfailed', request => events.push(`FAIL ${request.url}`));
|
||||||
server.setRedirect('/foo.html', '/empty.html');
|
server.setRedirect('/foo.html', '/empty.html');
|
||||||
const FOO_URL = STATIC_PREFIX + '/foo.html';
|
const FOO_URL = PREFIX + '/foo.html';
|
||||||
await page.navigate(FOO_URL);
|
await page.navigate(FOO_URL);
|
||||||
expect(events).toEqual([
|
expect(events).toEqual([
|
||||||
`GET ${FOO_URL}`,
|
`GET ${FOO_URL}`,
|
||||||
@ -733,7 +784,7 @@ describe('Puppeteer', function() {
|
|||||||
await page.evaluateOnInitialized(function(){
|
await page.evaluateOnInitialized(function(){
|
||||||
window.injected = 123;
|
window.injected = 123;
|
||||||
});
|
});
|
||||||
await page.navigate(STATIC_PREFIX + '/tamperable.html');
|
await page.navigate(PREFIX + '/tamperable.html');
|
||||||
expect(await page.evaluate(() => window.result)).toBe(123);
|
expect(await page.evaluate(() => window.result)).toBe(123);
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
@ -745,7 +796,7 @@ describe('Puppeteer', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should print to pdf', SX(async function() {
|
it('should print to pdf', SX(async function() {
|
||||||
await page.navigate(STATIC_PREFIX + '/grid.html');
|
await page.navigate(PREFIX + '/grid.html');
|
||||||
await page.printToPDF(outputFile);
|
await page.printToPDF(outputFile);
|
||||||
expect(fs.readFileSync(outputFile).byteLength).toBeGreaterThan(0);
|
expect(fs.readFileSync(outputFile).byteLength).toBeGreaterThan(0);
|
||||||
}));
|
}));
|
||||||
@ -760,7 +811,7 @@ describe('Puppeteer', function() {
|
|||||||
|
|
||||||
describe('Page.title', function() {
|
describe('Page.title', function() {
|
||||||
it('should return the page title', SX(async function(){
|
it('should return the page title', SX(async function(){
|
||||||
await page.navigate(STATIC_PREFIX + '/input/button.html');
|
await page.navigate(PREFIX + '/input/button.html');
|
||||||
expect(await page.title()).toBe('Button test');
|
expect(await page.title()).toBe('Button test');
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user