Skip to content
This repository was archived by the owner on Nov 24, 2018. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- `mousedown(selector: string): Chromeless<T>` and `mouseup(selector: string): Chromeless<T>` APIs [#118](https://github.com/graphcool/chromeless/pull/118) @criticalbh
- `focus(selector: string)` API [#132](https://github.com/graphcool/chromeless/pull/132) @criticalbh
- When using chromeless locally, chromeless will now boot chrome automatically [#120](https://github.com/graphcool/chromeless/pull/120) @joelgriffith
- `pdf()` API [#84](https://github.com/graphcool/chromeless/pull/84)


### Changed
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ const chromeless = new Chromeless({
- [`inputValue(selector: string)`](docs/api.md#api-inputvalue)
- [`exists(selector: string)`](docs/api.md#api-exists)
- [`screenshot()`](docs/api.md#api-screenshot)
- [`pdf()`](docs/api.md#api-pdf) - Not implemented yet
- [`pdf(options?: PdfOptions)`](docs/api.md#api-pdf)
- [`getHtml()`](docs/api.md#api-gethtml)
- [`cookiesGet()`](docs/api.md#api-cookiesget)
- [`cookiesGet(name: string)`](docs/api.md#api-cookiesget-name)
Expand Down
21 changes: 18 additions & 3 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Chromeless provides TypeScript typings.
- [`inputValue(selector: string)`](#api-inputvalue)
- [`exists(selector: string)`](#api-exists)
- [`screenshot()`](#api-screenshot)
- [`pdf()`](#api-pdf) - Not implemented yet
- [`pdf(options?: PdfOptions)`](#api-pdf)
- [`getHtml()`](#api-gethtml)
- [`cookiesGet()`](#api-cookiesget)
- [`cookiesGet(name: string)`](#api-cookiesget-name)
Expand Down Expand Up @@ -390,9 +390,24 @@ console.log(screenshot) // prints local file path or S3 URL

<a name="api-pdf" />

### pdf() - Not implemented yet
### pdf(options?: PdfOptions) - Chromeless<string>

Not implemented yet
Print to a PDF of the document as framed by the viewport.
When running Chromeless locally this returns the local file path to the PDF.
When run over the Chromeless Proxy service, a URL to the PDF on S3 is returned.

__Arguments__
- `options` - An object containing overrides for [printToPDF() parameters](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF)

__Example__

```js
const pdf = await chromeless
.goto('https://google.com/')
.pdf({landscape: true})

console.log(pdf) // prints local file path or S3 URL
```

---------------------------------------

Expand Down
8 changes: 7 additions & 1 deletion src/api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ChromeLocal from './chrome/local'
import ChromeRemote from './chrome/remote'
import Queue from './queue'
import { ChromelessOptions, Cookie, CookieQuery } from './types'
import { ChromelessOptions, Cookie, CookieQuery, PdfOptions } from './types'
import { getDebugOption } from './util'

export default class Chromeless<T extends any> implements Promise<T> {
Expand Down Expand Up @@ -186,6 +186,12 @@ export default class Chromeless<T extends any> implements Promise<T> {
return new Chromeless<string>({}, this)
}

pdf(options?: PdfOptions): Chromeless<string> {
this.lastReturnPromise = this.queue.process<string>({type: 'returnPDF', options})

return new Chromeless<string>({}, this)
}

/**
* Get the cookies for the current url
*/
Expand Down
33 changes: 32 additions & 1 deletion src/chrome/local-runtime.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as AWS from 'aws-sdk'
import { Client, Command, ChromelessOptions, Cookie, CookieQuery } from '../types'
import { Client, Command, ChromelessOptions, Cookie, CookieQuery, PdfOptions } from '../types'
import * as cuid from 'cuid'
import * as fs from 'fs'
import {
Expand All @@ -10,6 +10,7 @@ import {
evaluate,
screenshot,
getHtml,
pdf,
type,
getValue,
scrollTo,
Expand Down Expand Up @@ -53,6 +54,8 @@ export default class LocalRuntime {
return this.returnScreenshot()
case 'returnHtml':
return this.returnHtml()
case 'returnPDF':
return this.returnPDF(command.options)
case 'returnInputValue':
return this.returnInputValue(command.selector)
case 'type':
Expand Down Expand Up @@ -275,6 +278,34 @@ export default class LocalRuntime {
return await getHtml(this.client)
}

// Returns the S3 url or local file path
async returnPDF(options?: PdfOptions): Promise<string> {
const data = await pdf(this.client, options)

// check if S3 configured
if (process.env['CHROMELESS_S3_BUCKET_NAME'] && process.env['CHROMELESS_S3_BUCKET_URL']) {
const s3Path = `${cuid()}.pdf`
const s3 = new AWS.S3()
await s3.putObject({
Bucket: process.env['CHROMELESS_S3_BUCKET_NAME'],
Key: s3Path,
ContentType: 'application/pdf',
ACL: 'public-read',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably this should be configurable as well with an env variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be addressed as part of #113.

Body: new Buffer(data, 'base64'),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should also use Buffer.from() as new Buffer() is deprecated API in newer Node.js versions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be addressed as part of #113.

}).promise()

return `https://${process.env['CHROMELESS_S3_BUCKET_URL']}/${s3Path}`
}

// write to `/tmp` instead
else {
const filePath = `/tmp/${cuid()}.pdf`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should look into using a module that helps with tmp folders. This file tmp doesn't exist in windows systems

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With node 4 and above os.tmpdir() should do the trick.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be addressed as part of #113.

fs.writeFileSync(filePath, Buffer.from(data, 'base64'))

return filePath
}
}

private log(msg: string): void {
if (this.chromelessOptions.debug) {
console.log(msg)
Expand Down
20 changes: 20 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export type Command =
| {
type: 'returnHtml'
}
| {
type: 'returnPDF',
options?: PdfOptions
}
| {
type: 'scrollTo'
x: number
Expand Down Expand Up @@ -151,3 +155,19 @@ export interface CookieQuery {
secure?: boolean
session?: boolean
}

// https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF
export interface PdfOptions {
landscape?: boolean,
displayHeaderFooter?: boolean,
printBackground?: boolean,
scale?: number,
paperWidth?: number,
paperHeight?: number,
marginTop?: number,
marginBottom?: number,
marginLeft?: number,
marginRight?: number,
pageRanges?: string,
ignoreInvalidPageRanges?: boolean
}
10 changes: 9 additions & 1 deletion src/util.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as fs from 'fs'
import * as path from 'path'
import { Client, Cookie } from './types'
import { Client, Cookie, PdfOptions } from './types'

export const version: string = ((): string => {
if (fs.existsSync(path.join(__dirname, '../package.json'))) {
Expand Down Expand Up @@ -332,6 +332,14 @@ export async function getHtml(client: Client): Promise<string> {
return outerHTML
}

export async function pdf(client: Client, options?: PdfOptions): Promise<string> {
const {Page} = client

const pdf = await Page.printToPDF(options)

return pdf.data
}

export function getDebugOption(): boolean {
if (process && process.env && process.env['DEBUG'] && process.env['DEBUG'].includes('chromeless')) {
return true
Expand Down