Skip to content

Commit

Permalink
feat(Frame): Support options in addScriptTag and addStyleTag - fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
SamVerschueren committed Oct 11, 2017
1 parent ff08e45 commit ccc23cc
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 86 deletions.
66 changes: 33 additions & 33 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
+ [page.$$(selector)](#pageselector)
+ [page.$$eval(selector, pageFunction[, ...args])](#pageevalselector-pagefunction-args)
+ [page.$eval(selector, pageFunction[, ...args])](#pageevalselector-pagefunction-args)
+ [page.addScriptTag(url)](#pageaddscripttagurl)
+ [page.addStyleTag(url)](#pageaddstyletagurl)
+ [page.addScriptTag(options)](#pageaddscripttagoptions)
+ [page.addStyleTag(options)](#pageaddstyletagoptions)
+ [page.authenticate(credentials)](#pageauthenticatecredentials)
+ [page.click(selector[, options])](#pageclickselector-options)
+ [page.close()](#pageclose)
Expand All @@ -56,7 +56,6 @@
+ [page.goForward(options)](#pagegoforwardoptions)
+ [page.goto(url, options)](#pagegotourl-options)
+ [page.hover(selector)](#pagehoverselector)
+ [page.injectFile(filePath)](#pageinjectfilefilepath)
+ [page.keyboard](#pagekeyboard)
+ [page.mainFrame()](#pagemainframe)
+ [page.mouse](#pagemouse)
Expand Down Expand Up @@ -113,12 +112,11 @@
+ [frame.$$(selector)](#frameselector)
+ [frame.$$eval(selector, pageFunction[, ...args])](#frameevalselector-pagefunction-args)
+ [frame.$eval(selector, pageFunction[, ...args])](#frameevalselector-pagefunction-args)
+ [frame.addScriptTag(url)](#frameaddscripttagurl)
+ [frame.addStyleTag(url)](#frameaddstyletagurl)
+ [frame.addScriptTag(options)](#frameaddscripttagoptions)
+ [frame.addStyleTag(options)](#frameaddstyletagoptions)
+ [frame.childFrames()](#framechildframes)
+ [frame.evaluate(pageFunction, ...args)](#frameevaluatepagefunction-args)
+ [frame.executionContext()](#frameexecutioncontext)
+ [frame.injectFile(filePath)](#frameinjectfilefilepath)
+ [frame.isDetached()](#frameisdetached)
+ [frame.name()](#framename)
+ [frame.parentFrame()](#frameparentframe)
Expand Down Expand Up @@ -416,21 +414,27 @@ const html = await page.$eval('.main-container', e => e.outerHTML);

Shortcut for [page.mainFrame().$eval(selector, pageFunction)](#frameevalselector-pagefunction-args).

#### page.addScriptTag(url)
- `url` <[string]> Url of the `<script>` tag
- returns: <[Promise]> which resolves when the script's onload fires.
#### page.addScriptTag(options)
- `options` <[Object]>
- `url` <[string]> Url of a script to be added.
- `path` <[string]> Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
- `content` <[string]> Raw JavaScript content to be injected into frame.
- returns: <[Promise]> which resolves when the script's onload fires or when the script content was injected into frame.

Adds a `<script>` tag into the page with the desired url. Alternatively, a local JavaScript file can be injected via [`page.injectFile`](#pageinjectfilefilepath) method.
Adds a `<script>` tag into the page with the desired url or content.

Shortcut for [page.mainFrame().addScriptTag(url)](#frameaddscripttagurl).
Shortcut for [page.mainFrame().addScriptTag(options)](#frameaddscripttagoptions).

#### page.addStyleTag(url)
- `url` <[string]> Url of the `<link>` tag
- returns: <[Promise]> which resolves when the stylesheet's onload fires.
- `options` <[Object]>
- `url` <[string]> Url of the `<link>` tag.
- `path` <[string]> Path to the CSS file to be injected into frame. If `path` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
- `content` <[string]> Raw CSS content to be injected into frame.
- returns: <[Promise]> which resolves when the stylesheet's onload fires or when the CSS content was injected into frame.

Adds a `<link rel="stylesheet">` tag into the page with the desired url.
Adds a `<link rel="stylesheet">` tag into the page with the desired url or a `<style type="text/css">` tag with the content.

Shortcut for [page.mainFrame().addStyleTag(url)](#frameaddstyletagurl).
Shortcut for [page.mainFrame().addStyleTag(options)](#frameaddstyletagoptions).

#### page.authenticate(credentials)
- `credentials` <[Object]>
Expand Down Expand Up @@ -738,12 +742,6 @@ The `page.goto` will throw an error if:
This method fetches an element with `selector`, scrolls it into view if needed, and then uses [page.mouse](#pagemouse) to hover over the center of the element.
If there's no element matching `selector`, the method throws an error.

#### page.injectFile(filePath)
- `filePath` <[string]> Path to the JavaScript file to be injected into frame. If `filePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
- returns: <[Promise]> Promise which resolves when file gets successfully evaluated in frame.

Shortcut for [page.mainFrame().injectFile(filePath)](#frameinjectfilefilepath).

#### page.keyboard

- returns: <[Keyboard]>
Expand Down Expand Up @@ -1310,17 +1308,23 @@ const preloadHref = await frame.$eval('link[rel=preload]', el => el.href);
const html = await frame.$eval('.main-container', e => e.outerHTML);
```

#### frame.addScriptTag(url)
- `url` <[string]> Url of a script to be added
- returns: <[Promise]> Promise which resolves as the script gets added and loads.
#### frame.addScriptTag(options)
- `options` <[Object]>
- `url` <[string]> Url of a script to be added.
- `path` <[string]> Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
- `content` <[string]> Raw JavaScript content to be injected into frame.
- returns: <[Promise]> which resolves when the script's onload fires or when the script content was injected into frame.

Adds a `<script>` tag to the frame with the desired url. Alternatively, JavaScript can be injected to the frame via [`frame.injectFile`](#frameinjectfilefilepath) method.
Adds a `<script>` tag into the page with the desired url or content.

#### frame.addStyleTag(url)
- `url` <[string]> Url of a stylesheet to be added
- returns: <[Promise]> Promise which resolves when the script gets added and loads.
#### frame.addStyleTag(options)
- `options` <[Object]>
- `url` <[string]> Url of the `<link>` tag.
- `path` <[string]> Path to the CSS file to be injected into frame. If `path` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
- `content` <[string]> Raw CSS content to be injected into frame.
- returns: <[Promise]> which resolves when the stylesheet's onload fires or when the CSS content was injected into frame.

Adds a `<link rel="stylesheet">` tag to the frame with the desired url.
Adds a `<link rel="stylesheet">` tag into the page with the desired url or a `<style type="text/css">` tag with the content.

#### frame.childFrames()
- returns: <[Array]<[Frame]>>
Expand Down Expand Up @@ -1357,10 +1361,6 @@ await bodyHandle.dispose();
#### frame.executionContext()
- returns: <[ExecutionContext]> Execution context associated with this frame.

#### frame.injectFile(filePath)
- `filePath` <[string]> Path to the JavaScript file to be injected into frame. If `filePath` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd).
- returns: <[Promise]> Promise which resolves when file gets successfully evaluated in frame.

#### frame.isDetached()
- returns: <[boolean]>

Expand Down
84 changes: 63 additions & 21 deletions lib/FrameManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,55 +303,97 @@ class Frame {
}

/**
* @param {string} filePath
* @return {!Promise<*>}
* @param {Object} options
* @return {!Promise}
*/
async injectFile(filePath) {
let contents = await new Promise((resolve, reject) => {
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) return reject(err);
resolve(data);
async addScriptTag(options) {
if (typeof options.url === 'string') {
return this.evaluate(addScriptUrl, options.url);
}

if (typeof options.path === 'string') {
let contents = await new Promise((resolve, reject) => {
fs.readFile(options.path, 'utf8', (err, data) => {
if (err) return reject(err);
resolve(data);
});
});
});
contents += `//# sourceURL=` + filePath.replace(/\n/g,'');
return this.evaluate(contents);
}
contents += `//# sourceURL=` + options.path.replace(/\n/g, '');

/**
* @param {string} url
*/
async addScriptTag(url) {
return this.evaluate(addScriptTag, url);
return this.evaluate(addScriptContent, contents);
}

if (typeof options.content === 'string') {
return this.evaluate(addScriptContent, options.content);
}

/**
* @param {string} url
*/
function addScriptTag(url) {
function addScriptUrl(url) {
const script = document.createElement('script');
script.src = url;
const promise = new Promise(x => script.onload = x);
document.head.appendChild(script);
return promise;
}

/**
* @param {string} content
*/
function addScriptContent(content) {
const script = document.createElement('script');
script.type = 'text/javascript';
script.text = content;
document.head.appendChild(script);
}
}

/**
* @param {string} url
* @param {Object} options
* @return {!Promise}
*/
async addStyleTag(url) {
return this.evaluate(addStyleTag, url);
async addStyleTag(options) {
if (typeof options.url === 'string') {
return this.evaluate(addStyleUrl, options.url);
}

if (typeof options.path === 'string') {
const contents = await new Promise((resolve, reject) => {
fs.readFile(options.path, 'utf8', (err, data) => {
if (err) return reject(err);
resolve(data);
});
});

return this.evaluate(addStyleContent, contents);
}

if (typeof options.content === 'string') {
return this.evaluate(addStyleContent, options.content);
}

/**
* @param {string} url
*/
function addStyleTag(url) {
function addStyleUrl(url) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
const promise = new Promise(x => link.onload = x);
document.head.appendChild(link);
return promise;
}

/**
* @param {string} content
*/
function addStyleContent(content) {
const style = document.createElement('style');
style.type = 'text/css';
style.appendChild(document.createTextNode(content));
document.head.appendChild(style);
}
}

/**
Expand Down
19 changes: 6 additions & 13 deletions lib/Page.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,24 +246,17 @@ class Page extends EventEmitter {
}

/**
* @param {string} url
*/
async addScriptTag(url) {
return this.mainFrame().addScriptTag(url);
}

/**
* @param {string} url
* @param {Object} options
*/
async addStyleTag(url) {
return this.mainFrame().addStyleTag(url);
async addScriptTag(options) {
return this.mainFrame().addScriptTag(options);
}

/**
* @param {string} filePath
* @param {Object} options
*/
async injectFile(filePath) {
return this.mainFrame().injectFile(filePath);
async addStyleTag(options) {
return this.mainFrame().addStyleTag(options);
}

/**
Expand Down
47 changes: 28 additions & 19 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,21 +425,6 @@ describe('Page', function() {
}));
});

describe('Page.injectFile', function() {
it('should work', SX(async function() {
const helloPath = path.join(__dirname, 'assets', 'injectedfile.js');
await page.injectFile(helloPath);
const result = await page.evaluate(() => __injected);
expect(result).toBe(42);
}));
it('should include sourcemap', SX(async function() {
const helloPath = path.join(__dirname, 'assets', 'injectedfile.js');
await page.injectFile(helloPath);
const result = await page.evaluate(() => __injectedError.stack);
expect(result).toContain(path.join('assets', 'injectedfile.js'));
}));
});

describe('Frame.context', function() {
const FrameUtils = require('./frame-utils');
it('should work', SX(async function() {
Expand Down Expand Up @@ -2035,19 +2020,43 @@ describe('Page', function() {
});

describe('Page.addScriptTag', function() {
it('should work', SX(async function() {
it('should work with a url', SX(async function() {
await page.goto(EMPTY_PAGE);
await page.addScriptTag('/injectedfile.js');
await page.addScriptTag({ url: '/injectedfile.js' });
expect(await page.evaluate(() => __injected)).toBe(42);
}));

it('should work with a path', SX(async function() {
await page.goto(EMPTY_PAGE);
await page.addScriptTag({ path: path.join(__dirname, 'assets/injectedfile.js') });
expect(await page.evaluate(() => __injected)).toBe(42);
}));

it('should work with content', SX(async function() {
await page.goto(EMPTY_PAGE);
await page.addScriptTag({ content: 'window.__injected = 35;' });
expect(await page.evaluate(() => __injected)).toBe(35);
}));
});

describe('Page.addStyleTag', function() {
it('should work', SX(async function() {
it('should work with a url', SX(async function() {
await page.goto(EMPTY_PAGE);
await page.addStyleTag({ url: '/injectedstyle.css' });
expect(await page.evaluate(`window.getComputedStyle(document.querySelector('body')).getPropertyValue('background-color')`)).toBe('rgb(255, 0, 0)');
}));

it('should work with a path', SX(async function() {
await page.goto(EMPTY_PAGE);
await page.addStyleTag('/injectedstyle.css');
await page.addStyleTag({ path: path.join(__dirname, 'assets/injectedstyle.css') });
expect(await page.evaluate(`window.getComputedStyle(document.querySelector('body')).getPropertyValue('background-color')`)).toBe('rgb(255, 0, 0)');
}));

it('should work with content', SX(async function() {
await page.goto(EMPTY_PAGE);
await page.addStyleTag({ content: 'body { background-color: green; }' });
expect(await page.evaluate(`window.getComputedStyle(document.querySelector('body')).getPropertyValue('background-color')`)).toBe('rgb(0, 128, 0)');
}));
});

describe('Page.url', function() {
Expand Down

0 comments on commit ccc23cc

Please sign in to comment.