diff --git a/CHANGELOG.md b/CHANGELOG.md index 832d506b..e478090a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Added - CODE_OF_CONDUCT.md, CONTRIBUTING.md +- `getHtml()` and `setHtml()` APIs. [#112](https://github.com/graphcool/chromeless/pull/112), [#74](https://github.com/graphcool/chromeless/issues/74) ### Changed - `.evaluate()` now returns the resulting value or a Promise [#110](https://github.com/graphcool/chromeless/pull/110) @joelgriffith diff --git a/README.md b/README.md index 7b3f11fa..34938203 100644 --- a/README.md +++ b/README.md @@ -153,12 +153,14 @@ const chromeless = new Chromeless({ - [`mousedown()`](docs/api.md#api-mousedown) - Not implemented yet - [`mouseup()`](docs/api.md#api-mouseup) - Not implemented yet - [`scrollTo(x: number, y: number)`](docs/api.md#api-scrollto) +- [`setHtml(html: string)`](docs/api.md#api-sethtml) - [`viewport(width: number, height: number)`](docs/api.md#api-viewport) - [`evaluate(fn: (...args: any[]) => void, ...args: any[])`](docs/api.md#api-evaluate) - [`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 +- [`getHtml()`](docs/api.md#api-gethtml) - [`cookiesGet()`](docs/api.md#api-cookiesget) - [`cookiesGet(name: string)`](docs/api.md#api-cookiesget-name) - [`cookiesGet(query: CookieQuery)`](docs/api.md#api-cookiesget-query) - Not implemented yet diff --git a/docs/api.md b/docs/api.md index 7a750826..43e1bcb5 100644 --- a/docs/api.md +++ b/docs/api.md @@ -20,12 +20,14 @@ Chromeless provides TypeScript typings. - [`mousedown()`](#api-mousedown) - Not implemented yet - [`mouseup()`](#api-mouseup) - Not implemented yet - [`scrollTo(x: number, y: number)`](#api-scrollto) +- [`setHtml(html: string)`](#api-sethtml) - [`viewport(width: number, height: number)`](#api-viewport) - [`evaluate(fn: (...args: any[]) => void, ...args: any[])`](#api-evaluate) - [`inputValue(selector: string)`](#api-inputvalue) - [`exists(selector: string)`](#api-exists) - [`screenshot()`](#api-screenshot) - [`pdf()`](#api-pdf) - Not implemented yet +- [`getHtml()`](#api-gethtml) - [`cookiesGet()`](#api-cookiesget) - [`cookiesGet(name: string)`](#api-cookiesget-name) - [`cookiesGet(query: CookieQuery)`](#api-cookiesget-query) - Not implemented yet @@ -254,6 +256,23 @@ await chromeless.scrollTo(500, 0) --------------------------------------- + + +### setHtml(html: string): Chromeless + +Sets given markup as the document's HTML. + +__Arguments__ +- `html` - HTML to set as the document's markup. + +__Example__ + +```js +await chromeless.setHtml('

Hello world!

') +``` + +--------------------------------------- +
### viewport(width: number, height: number) @@ -359,6 +378,24 @@ Not implemented yet --------------------------------------- + + +### getHtml(): Chromeless + +Get full HTML of the loaded page. + +__Example__ + +```js +const html = await chromeless + .setHtml('

Hello world!

') + .getHtml() + +console.log(html) //

Hello world!

+``` + +--------------------------------------- +
### cookiesGet(): Chromeless diff --git a/src/api.ts b/src/api.ts index 75d8c184..49714299 100644 --- a/src/api.ts +++ b/src/api.ts @@ -142,6 +142,12 @@ export default class Chromeless implements Promise { return this } + setHtml(html: string): Chromeless { + this.queue.enqueue({type: 'setHtml', html}) + + return this + } + viewport(width: number, height: number): Chromeless { throw new Error('Not implemented yet') } @@ -170,6 +176,12 @@ export default class Chromeless implements Promise { return new Chromeless({}, this) } + getHtml(): Chromeless { + this.lastReturnPromise = this.queue.process({type: 'returnHtml'}) + + return new Chromeless({}, this) + } + /** * Get the cookies for the current url */ diff --git a/src/chrome/local-runtime.ts b/src/chrome/local-runtime.ts index 8060be57..38d8de5f 100644 --- a/src/chrome/local-runtime.ts +++ b/src/chrome/local-runtime.ts @@ -9,9 +9,11 @@ import { click, evaluate, screenshot, + getHtml, type, getValue, scrollTo, + setHtml, press, clearCookies, getCookies, @@ -49,6 +51,8 @@ export default class LocalRuntime { return this.returnExists(command.selector) case 'returnScreenshot': return this.returnScreenshot() + case 'returnHtml': + return this.returnHtml() case 'returnInputValue': return this.returnInputValue(command.selector) case 'type': @@ -57,6 +61,8 @@ export default class LocalRuntime { return this.press(command.keyCode, command.count, command.modifiers) case 'scrollTo': return this.scrollTo(command.x, command.y) + case 'setHtml': + return this.setHtml(command.html) case 'cookiesClearAll': return this.cookiesClearAll() case 'cookiesGet': @@ -114,6 +120,10 @@ export default class LocalRuntime { return scrollTo(this.client, x, y) } + private async setHtml(html: string): Promise { + await setHtml(this.client, html) + } + async type(text: string, selector?: string): Promise { if (selector) { if (this.chromlessOptions.implicitWait) { @@ -208,10 +218,14 @@ export default class LocalRuntime { } } + async returnHtml(): Promise { + return await getHtml(this.client) + } + private log(msg: string): void { if (this.chromlessOptions.debug) { console.log(msg) } } -} \ No newline at end of file +} diff --git a/src/types.ts b/src/types.ts index f0bc1ac5..7a9b25d7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,7 @@ export interface Client { Network: any Page: any + DOM: any Input: any Runtime: any Emulation: any @@ -76,11 +77,18 @@ export type Command = | { type: 'returnScreenshot' } + | { + type: 'returnHtml' + } | { type: 'scrollTo' x: number y: number } + | { + type: 'setHtml', + html: string + } | { type: 'press' keyCode: number diff --git a/src/util.ts b/src/util.ts index 1b54a855..8434eaa6 100644 --- a/src/util.ts +++ b/src/util.ts @@ -238,6 +238,13 @@ export async function scrollTo(client: Client, x: number, y: number): Promise { + const {Page} = client + + const {frameTree: {frame: {id: frameId}}} = await Page.getResourceTree() + await Page.setDocumentContent({frameId, html}) +} + export async function getCookies(client: Client, nameOrQuery?: string | Cookie): Promise { if (nameOrQuery) { throw new Error('Not yet implemented') @@ -290,6 +297,14 @@ export async function screenshot(client: Client): Promise { return screenshot.data } +export async function getHtml(client: Client): Promise { + const {DOM} = client + + const {root: {nodeId}} = await DOM.getDocument() + const {outerHTML} = await DOM.getOuterHTML({nodeId}) + return outerHTML +} + export function getDebugOption(): boolean { if (process && process.env && process.env['DEBUG'] && process.env['DEBUG'].includes('chromeless')) { return true