Skip to content

Commit

Permalink
chore: add "puppeteer" example (#77)
Browse files Browse the repository at this point in the history
* adds puppeteer example

* simplifies examples

* chore: code style

* chore: rename test file

* scaffolds simple app to demonstrate testing modules in the browser

* chore: remove unnecessary markup

* chore: move `util` to `tests/setup`

* refactor: individual suites w/ helpers

* chore: add readme

Co-authored-by: Luke Edwards <luke.edwards05@gmail.com>
  • Loading branch information
AlexVipond and lukeed committed Nov 30, 2020
1 parent e419ff9 commit 53ac99a
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 0 deletions.
11 changes: 11 additions & 0 deletions examples/puppeteer/index.html
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>uvu + Puppeteer</title>
</head>
<body>
<script type="module" src="/src/app.js"></script>
</body>
</html>
13 changes: 13 additions & 0 deletions examples/puppeteer/package.json
@@ -0,0 +1,13 @@
{
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"test": "uvu tests -i setup"
},
"devDependencies": {
"puppeteer": "^5.5.0",
"uvu": "^0.5.0",
"vite": "1.0.0-rc.13"
}
}
27 changes: 27 additions & 0 deletions examples/puppeteer/readme.md
@@ -0,0 +1,27 @@
# Example: Puppeteer

This example runs [Puppeteer](https://www.npmjs.com/package/puppeteer) programmatically.

In order to invoke and test against source (`/src`) files, this example also uses [`vite`](https://www.npmjs.com/package/vite) to run a local devserver. Puppeteer connects to this devserver to access the `window` globals that `src/math.js` and `src/utils.js` are globally mounted to.

> **Note:** Window globals are not required in order for `uvu` to work with `puppeteer`! <br>You may, for example, load your Preact, Svelte, Vue, ... etc application inside the devserver & interact with it through Puppeteer APIs!
## Setup

```sh
$ npm install
```

## Testing

```sh
# start devserver
$ npm run dev

# run tests (2nd terminal)
$ npm test
```

## License

MIT
5 changes: 5 additions & 0 deletions examples/puppeteer/src/app.js
@@ -0,0 +1,5 @@
import * as math from './math.js';
import * as utils from './utils.js';

window.__MATH__ = math;
window.__UTILS__ = utils;
3 changes: 3 additions & 0 deletions examples/puppeteer/src/math.js
@@ -0,0 +1,3 @@
export const sum = (a, b) => a + b;
export const div = (a, b) => a / b;
export const mod = (a, b) => a % b;
7 changes: 7 additions & 0 deletions examples/puppeteer/src/utils.js
@@ -0,0 +1,7 @@
export function capitalize(str) {
return str[0].toUpperCase() + str.substring(1);
}

export function dashify(str) {
return str.replace(/([a-zA-Z])(?=[A-Z\d])/g, '$1-').toLowerCase();
}
28 changes: 28 additions & 0 deletions examples/puppeteer/tests/index.js
@@ -0,0 +1,28 @@
import { test } from 'uvu';
import * as assert from 'uvu/assert';
import * as ENV from './setup/puppeteer.js'

test.before(ENV.setup);
test.after(ENV.reset);

test('can fetch data!', async context => {
const data = await context.page.evaluate(() => {
return fetch('https://httpbin.org/get').then(r => r.json());
});

assert.type(data, 'object');
assert.is(data.url, 'https://httpbin.org/get');
});

test('can select elements!', async context => {
await context.page.goto('http://example.com/');

const text = await context.page.evaluate(() => {
return document.querySelector('h1').textContent;
});

assert.type(text, 'string');
assert.is(text, 'Example Domain');
});

test.run();
73 changes: 73 additions & 0 deletions examples/puppeteer/tests/math.js
@@ -0,0 +1,73 @@
import { suite } from 'uvu';
import * as assert from 'uvu/assert';
import * as ENV from './setup/puppeteer.js'

const sum = suite('sum');
sum.before(ENV.setup);
sum.before.each(ENV.homepage);
sum.after(ENV.reset);

sum('should be a function', async context => {
assert.is(
await context.page.evaluate(() => typeof window.__MATH__.sum),
'function'
);
});

sum('should compute values', async context => {
const { page } = context;

assert.is(await page.evaluate(() => window.__MATH__.sum(1, 2)), 3);
assert.is(await page.evaluate(() => window.__MATH__.sum(-1, -2)), -3);
assert.is(await page.evaluate(() => window.__MATH__.sum(-1, 1)), 0);
});

sum.run();

// ---

const div = suite('div');
div.before(ENV.setup);
div.before.each(ENV.homepage);
div.after(ENV.reset);

div('should be a function', async context => {
assert.is(
await context.page.evaluate(() => typeof window.__MATH__.div),
'function'
);
});

div('should compute values', async context => {
const { page } = context;

assert.is(await page.evaluate(() => window.__MATH__.div(1, 2)), 0.5);
assert.is(await page.evaluate(() => window.__MATH__.div(-1, -2)), 0.5);
assert.is(await page.evaluate(() => window.__MATH__.div(-1, 1)), -1);
});

div.run();

// ---

const mod = suite('mod');
mod.before(ENV.setup);
mod.before.each(ENV.homepage);
mod.after(ENV.reset);

mod('should be a function', async context => {
assert.is(
await context.page.evaluate(() => typeof window.__MATH__.mod),
'function'
);
});

mod('should compute values', async context => {
const { page } = context;

assert.is(await page.evaluate(() => window.__MATH__.mod(1, 2)), 1);
assert.is(await page.evaluate(() => window.__MATH__.mod(-1, -2)), -1);
assert.is(await page.evaluate(() => window.__MATH__.mod(7, 4)), 3);
});

mod.run();
19 changes: 19 additions & 0 deletions examples/puppeteer/tests/setup/puppeteer.js
@@ -0,0 +1,19 @@
import Chrome from 'puppeteer';

// Launch the browser
// Add `browser` and `page` to context
export async function setup(context) {
context.browser = await Chrome.launch();
context.page = await context.browser.newPage();
}

// Close everything on suite completion
export async function reset(context) {
await context.page.close();
await context.browser.close();
}

// Navigate to homepage
export async function homepage(context) {
await context.page.goto('http://localhost:3000');
}
58 changes: 58 additions & 0 deletions examples/puppeteer/tests/utils.js
@@ -0,0 +1,58 @@
import { suite } from 'uvu';
import * as assert from 'uvu/assert';
import * as ENV from './setup/puppeteer.js'

const capitalize = suite('capitalize');
capitalize.before(ENV.setup);
capitalize.before.each(ENV.homepage);
capitalize.after(ENV.reset);

capitalize('should be a function', async context => {
assert.is(
await context.page.evaluate(() => typeof window.__UTILS__.capitalize),
'function'
);
});

capitalize('should capitalize a word', async context => {
assert.is(
await context.page.evaluate(() => window.__UTILS__.capitalize('hello')),
'Hello'
);
});

capitalize('should only capitalize the 1st word', async context => {
assert.is(
await context.page.evaluate(() => window.__UTILS__.capitalize('foo bar')),
'Foo bar'
);
});

capitalize.run();

// ---

const dashify = suite('dashify');
dashify.before(ENV.setup);
dashify.before.each(ENV.homepage);
dashify.after(ENV.reset);

dashify('should be a function', async context => {
assert.is(
await context.page.evaluate(() => typeof window.__UTILS__.dashify),
'function'
);
});

dashify('should replace camelCase with dash-case', async context => {
const { page } = context;
assert.is(await page.evaluate(() => window.__UTILS__.dashify('fooBar')), 'foo-bar');
assert.is(await page.evaluate(() => window.__UTILS__.dashify('FooBar')), 'foo-bar');
});

dashify('should ignore lowercase', async context => {
const { page } = context;
assert.is(await page.evaluate(() => window.__UTILS__.dashify('foobar')), 'foobar');
});

dashify.run();

0 comments on commit 53ac99a

Please sign in to comment.