Skip to content

Commit 348916f

Browse files
sterenfhinkel
authored andcommitted
Add puppeteer sample (Headless Chrome) (#625)
1 parent 6fc023b commit 348916f

File tree

5 files changed

+156
-0
lines changed

5 files changed

+156
-0
lines changed

appengine/headless-chrome/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Headless Chrome on Google App Engine
2+
3+
This sample application demonstrates how to use Headless Chrome via the [Puppeteer](https://developers.google.com/web/tools/puppeteer/) module to take screenshots of webpages on [Google App Engine](https://cloud.google.com/appengine) Node.js [standard environment](https://cloud.google.com/appengine/docs/standard/nodejs).
4+
5+
## Running and deploying
6+
7+
Refer to the [appengine/README.md](../README.md) file for instructions on running and deploying.

appengine/headless-chrome/app.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
Copyright 2018 Google LLC
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
'use strict';
17+
18+
// [START full_sample]
19+
const express = require('express');
20+
const puppeteer = require('puppeteer');
21+
const app = express();
22+
23+
app.use(async (req, res) => {
24+
const url = req.query.url;
25+
26+
if (!url) {
27+
return res.send('Please provide URL as GET parameter, for example: <a href="/?url=https://example.com">?url=https://example.com</a>');
28+
}
29+
30+
// [START browser]
31+
const browser = await puppeteer.launch({
32+
args: ['--no-sandbox', '--disable-setuid-sandbox']
33+
});
34+
// [END browser]
35+
const page = await browser.newPage();
36+
await page.goto(url);
37+
const imageBuffer = await page.screenshot();
38+
await browser.close();
39+
40+
res.set('Content-Type', 'image/png');
41+
res.send(imageBuffer);
42+
});
43+
44+
const server = app.listen(process.env.PORT || 8080, err => {
45+
if (err) return console.error(err);
46+
const port = server.address().port;
47+
console.info(`App listening on port ${port}`);
48+
});
49+
// [END full_sample]
50+
51+
module.exports = app;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2018, Google LLC
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License
13+
14+
# [START app_yaml]
15+
runtime: nodejs8
16+
instance_class: F4_1G
17+
# [END app_yaml]
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "headless-chrome-sample",
3+
"engines": {
4+
"node": "8.x"
5+
},
6+
"version": "1.0.0",
7+
"description": "An example of taking screenshot with Puppeteer (Headless Chrome) in Node.js on Google App Engine.",
8+
"scripts": {
9+
"start": "node app.js",
10+
"system-test": "repo-tools test app",
11+
"unit-test": "ava --verbose test/*.test.js",
12+
"lint": "repo-tools lint",
13+
"pretest": "npm run lint",
14+
"test": "npm run unit-test && npm run system-test"
15+
},
16+
"repository": {
17+
"type": "git",
18+
"url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
19+
},
20+
"author": {
21+
"name": "Google LLC"
22+
},
23+
"license": "Apache-2.0",
24+
"dependencies": {
25+
"express": "^4.16.3",
26+
"puppeteer": "^1.2.0"
27+
},
28+
"devDependencies": {
29+
"@google-cloud/nodejs-repo-tools": "2.3.0",
30+
"ava": "^0.25.0",
31+
"semistandard": "^12.0.1"
32+
},
33+
"cloud-repo-tools": {
34+
"test": {
35+
"app": {
36+
"msg": "Please provide URL"
37+
}
38+
},
39+
"requiresKeyFile": true,
40+
"requiresProjectId": true
41+
}
42+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2017, Google, Inc.
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
// NOTE:
15+
// This app can only be fully tested when deployed, because
16+
// Pub/Sub requires a live endpoint URL to hit. Nevertheless,
17+
// these tests mock it and partially test it locally.
18+
19+
'use strict';
20+
21+
const test = require(`ava`);
22+
const path = require(`path`);
23+
const utils = require(`@google-cloud/nodejs-repo-tools`);
24+
25+
const cwd = path.join(__dirname, `../`);
26+
const requestObj = utils.getRequest({ cwd: cwd });
27+
28+
test.serial.cb(`should return a screenshot`, t => {
29+
requestObj
30+
.get(`/?url=https://example.com`)
31+
.send()
32+
.expect(200)
33+
.expect(response => {
34+
t.is(response.type, `image/png`);
35+
t.true(response.body instanceof Buffer);
36+
t.true(response.body.length > 0);
37+
})
38+
.end(t.end);
39+
});

0 commit comments

Comments
 (0)