diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3dc3837..c57bb94 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,15 +10,17 @@ jobs: fail-fast: false matrix: node-version: + - 18 + - 16 - 14 steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - run: npm install - run: npm test - - uses: codecov/codecov-action@v1 - if: matrix.node-version == 14 + - uses: codecov/codecov-action@v3 + if: matrix.node-version == 16 with: fail_ci_if_error: true diff --git a/example.js b/example.js new file mode 100644 index 0000000..bc8800b --- /dev/null +++ b/example.js @@ -0,0 +1,10 @@ +import Pageres from './dist/index.js'; + +await new Pageres({delay: 2}) + .source('https://github.com/sindresorhus/pageres', ['480x320', '1024x768'], {crop: true}) + .source('https://sindresorhus.com', ['1280x1024', '1920x1080']) + .source('data:text/html,

Awesome!

', ['1024x768']) + .destination('screenshots') + .run(); + +console.log('Finished generating screenshots!'); diff --git a/readme.md b/readme.md index 8a812de..ec32d8c 100644 --- a/readme.md +++ b/readme.md @@ -21,10 +21,10 @@ Note to Linux users: If you get a "No usable sandbox!" error, you need to enable import Pageres from 'pageres'; await new Pageres({delay: 2}) - .src('https://github.com/sindresorhus/pageres', ['480x320', '1024x768'], {crop: true}) - .src('https://sindresorhus.com', ['1280x1024', '1920x1080']) - .src('data:text/html,

Awesome!

', ['1024x768']) - .dest('screenshots') + .source('https://github.com/sindresorhus/pageres', ['480x320', '1024x768'], {crop: true}) + .source('https://sindresorhus.com', ['1280x1024', '1920x1080']) + .source('data:text/html,

Awesome!

', ['1024x768']) + .destination('screenshots') .run(); console.log('Finished generating screenshots!'); @@ -197,14 +197,14 @@ await new Pageres({ await page.waitForSelector('.finished'); } }) - .src('https://github.com/sindresorhus/pageres', ['480x320', '1024x768', 'iphone 5s'], {crop: true}) - .dest(__dirname) + .source('https://github.com/sindresorhus/pageres', ['480x320', '1024x768', 'iphone 5s'], {crop: true}) + .destination('screenshots') .run(); console.log('Finished generating screenshots!'); ``` -### pageres.src(url, sizes, options?) +### pageres.source(url, sizes, options?) Add a page to screenshot. @@ -232,7 +232,7 @@ Type: `object` Options set here will take precedence over the ones set in the constructor. -### pageres.dest(directory) +### pageres.destination(directory) Set the destination directory. diff --git a/source/index.ts b/source/index.ts index f5d346f..4d2af4e 100644 --- a/source/index.ts +++ b/source/index.ts @@ -179,8 +179,8 @@ export type Options = { await page.waitForSelector('.finished'); } }) - .src('https://github.com/sindresorhus/pageres', ['480x320', '1024x768'], {crop: true}) - .dest('screenshots') + .source('https://github.com/sindresorhus/pageres', ['480x320', '1024x768'], {crop: true}) + .destination('screenshots') .run(); console.log('Finished generating screenshots!'); @@ -190,7 +190,7 @@ export type Options = { }; /** -A page to screenshot added in {@link Pageres.src}. +A page to screenshot added in {@link Pageres.source}. */ export type Source = { /** @@ -210,7 +210,7 @@ export type Source = { }; /** -A destination directory set in {@link Pageres.dest}. +A destination directory set in {@link Pageres.destination}. */ export type Destination = string; @@ -241,7 +241,7 @@ Capture screenshots of websites in various resolutions. A good way to make sure */ export default class Pageres extends EventEmitter { readonly #options: Writable; - #stats: Stats = {} as Stats; + #stats: Stats = {} as Stats; // eslint-disable-line @typescript-eslint/consistent-type-assertions readonly #items: Screenshot[] = []; readonly #sizes: string[] = []; readonly #urls: string[] = []; @@ -266,7 +266,7 @@ export default class Pageres extends EventEmitter { @returns List of pages that have been already been added. */ - src(): Source[]; + source(): Source[]; /** Add a page to screenshot. @@ -283,14 +283,14 @@ export default class Pageres extends EventEmitter { import Pageres from 'pageres'; const pageres = new Pageres({delay: 2}) - .src('https://github.com/sindresorhus/pageres', ['480x320', '1024x768'], {crop: true}) - .src('https://sindresorhus.com', ['1280x1024', '1920x1080']) - .src('data:text/html,

Awesome!

', ['1024x768'], {delay: 1}); + .source('https://github.com/sindresorhus/pageres', ['480x320', '1024x768'], {crop: true}) + .source('https://sindresorhus.com', ['1280x1024', '1920x1080']) + .source('data:text/html,

Awesome!

', ['1024x768'], {delay: 1}); ``` */ - src(url: string, sizes: readonly string[], options?: Options): this; + source(url: string, sizes: readonly string[], options?: Options): this; - src(url?: string, sizes?: readonly string[], options?: Options): this | Source[] { + source(url?: string, sizes?: readonly string[], options?: Options): this | Source[] { if (url === undefined) { return this.#_source; } @@ -311,7 +311,7 @@ export default class Pageres extends EventEmitter { /** Get the destination directory. */ - dest(): Destination; + destination(): Destination; /** Set the destination directory. @@ -321,13 +321,13 @@ export default class Pageres extends EventEmitter { import Pageres from 'pageres'; const pageres = new Pageres() - .src('https://github.com/sindresorhus/pageres', ['480x320']) - .dest('screenshots'); + .source('https://github.com/sindresorhus/pageres', ['480x320']) + .destination('screenshots'); ``` */ - dest(directory: Destination): this; + destination(directory: Destination): this; - dest(directory?: Destination): this | Destination { + destination(directory?: Destination): this | Destination { if (directory === undefined) { return this.#_destination; } @@ -351,13 +351,13 @@ export default class Pageres extends EventEmitter { import Pageres from 'pageres'; await new Pageres({delay: 2}) - .src('https://sindresorhus.com', ['1280x1024']) - .dest('screenshots') + .source('https://sindresorhus.com', ['1280x1024']) + .destination('screenshots') .run(); ``` */ async run(): Promise { - await Promise.all(this.src().map(async (source: Source): Promise => { + await Promise.all(this.source().map(async (source: Source): Promise => { const options = { ...this.#options, ...source.options, @@ -393,7 +393,7 @@ export default class Pageres extends EventEmitter { this.#stats.sizes = arrayUniq(this.#sizes).length; this.#stats.screenshots = this.#items.length; - if (!this.dest()) { + if (!this.destination()) { return this.#items; } @@ -410,8 +410,8 @@ export default class Pageres extends EventEmitter { import Pageres from 'pageres'; const pageres = new Pageres({delay: 2}) - .src('https://sindresorhus.com', ['1280x1024', '1920x1080']) - .dest('screenshots'); + .source('https://sindresorhus.com', ['1280x1024', '1920x1080']) + .destination('screenshots'); await pageres.run(); @@ -450,8 +450,8 @@ export default class Pageres extends EventEmitter { private async save(screenshots: Screenshot[]): Promise { await Promise.all(screenshots.map(async screenshot => { - await makeDir(this.dest()); - const dest = path.join(this.dest(), screenshot.filename); + await makeDir(this.destination()); + const dest = path.join(this.destination(), screenshot.filename); await fsPromises.writeFile(dest, screenshot); })); } diff --git a/test/cookie.ts b/test/cookie.ts index d609f2c..e096035 100644 --- a/test/cookie.ts +++ b/test/cookie.ts @@ -10,7 +10,7 @@ async function cookieTest(input: string | Cookie, t: ExecutionContext): Promise< const server = await createCookieServer(); const screenshots = await new Pageres({cookies: [input]}) - .src(server.url, ['320x480']) + .source(server.url, ['320x480']) .run(); server.close(); diff --git a/test/test.ts b/test/test.ts index 4425d0a..3305b77 100644 --- a/test/test.ts +++ b/test/test.ts @@ -43,37 +43,28 @@ test('expose a constructor', t => { t.is(typeof Pageres, 'function'); }); -test('add a source', t => { - const pageres = new Pageres().src(server.url, ['1280x1024', '1920x1080']); - t.is((pageres as any)._source[0].url, server.url); -}); - -test('set destination directory', t => { - t.is((new Pageres().dest('tmp') as any)._destination, 'tmp'); -}); - -test('`.src()` - error if no correct `url` is specified', t => { +test('`.source()` - error if no correct `url` is specified', t => { t.throws(() => { - new Pageres().src('', ['1280x1024', '1920x1080']); + new Pageres().source('', ['1280x1024', '1920x1080']); }, {message: 'URL required'}); }); -test('`.src()` - error if no `sizes` is specified', t => { +test('`.source()` - error if no `sizes` is specified', t => { t.throws(() => { - new Pageres().src(server.url, []); + new Pageres().source(server.url, []); }, {message: 'Sizes required'}); }); -test('`.dest()` - error if no correct `directory` is specified', t => { +test('`.destination()` - error if no correct `directory` is specified', t => { t.throws(() => { - new Pageres().dest(''); + new Pageres().destination(''); }, {message: 'Directory required'}); }); test('generate screenshots', async t => { const screenshots = await new Pageres() - .src(server.url, ['480x320', '1024x768', 'iphone 5s']) - .src(server.url, ['1280x1024', '1920x1080']) + .source(server.url, ['480x320', '1024x768', 'iphone 5s']) + .source(server.url, ['1280x1024', '1920x1080']) .run(); t.is(screenshots.length, 5); @@ -84,7 +75,7 @@ test('generate screenshots', async t => { test('generate screenshots - multiple sizes for one URL', async t => { const screenshots = await new Pageres() - .src(server.url, ['1280x1024', '1920x1080']) + .source(server.url, ['1280x1024', '1920x1080']) .run(); t.is(screenshots.length, 2); @@ -95,12 +86,12 @@ test('generate screenshots - multiple sizes for one URL', async t => { test('save filename with hash', async t => { const screenshots = await new Pageres() - .src('https://example.com#', ['480x320']) - .src('https://example.com/#/', ['480x320']) - .src('https://example.com/#/@user', ['480x320']) - .src('https://example.com/#/product/listing', ['480x320']) - .src('https://example.com/#!/bang', ['480x320']) - .src('https://example.com#readme', ['480x320']) + .source('https://example.com#', ['480x320']) + .source('https://example.com/#/', ['480x320']) + .source('https://example.com/#/@user', ['480x320']) + .source('https://example.com/#/product/listing', ['480x320']) + .source('https://example.com/#!/bang', ['480x320']) + .source('https://example.com#readme', ['480x320']) .run(); t.is(screenshots.length, 6); @@ -117,29 +108,30 @@ test('save filename with hash', async t => { t.true(screenshots[0].length > 1000); }); -test('success message', async t => { +test.serial('success message', async t => { const stub = sinonStub(console, 'log'); - const pageres = new Pageres().src(server.url, ['480x320', '1024x768', 'iphone 5s']); + const pageres = new Pageres().source(server.url, ['480x320', '1024x768', 'iphone 5s']); await pageres.run(); pageres.successMessage(); - t.true(stub.firstCall.args[0].includes('Generated 3 screenshots from 1 url and 1 size')); + const [message] = stub.firstCall.args; + t.true(message.includes('Generated 3 screenshots from 1 url and 1 size'), message); // eslint-disable-line ava/assertion-arguments stub.restore(); }); test('remove special characters from the URL to create a valid filename', async t => { - const screenshots = await new Pageres().src(`${server.url}?query=pageres*|<>:"\\`, ['1024x768']).run(); + const screenshots = await new Pageres().source(`${server.url}?query=pageres*|<>:"\\`, ['1024x768']).run(); t.is(screenshots.length, 1); t.is(screenshots[0].filename, `${server.host}!${server.port}!query=pageres-1024x768.png`); }); test('`delay` option', async t => { const now = Date.now(); - await new Pageres({delay: 2}).src(server.url, ['1024x768']).run(); + await new Pageres({delay: 2}).source(server.url, ['1024x768']).run(); t.true(Date.now() - now > 2000); }); test('`crop` option', async t => { - const screenshots = await new Pageres({crop: true}).src(server.url, ['1024x768']).run(); + const screenshots = await new Pageres({crop: true}).source(server.url, ['1024x768']).run(); t.is(screenshots[0].filename, `${server.host}!${server.port}-1024x768-cropped.png`); const size = imageSize(screenshots[0]) as any; @@ -148,7 +140,7 @@ test('`crop` option', async t => { }); test('`css` option', async t => { - const screenshots = await new Pageres({css: 'body { background-color: red !important; }'}).src(server.url, ['1024x768']).run(); + const screenshots = await new Pageres({css: 'body { background-color: red !important; }'}).source(server.url, ['1024x768']).run(); const pixels = await getPngPixels(screenshots[0]); t.is(pixels[0], 255); t.is(pixels[1], 0); @@ -158,7 +150,7 @@ test('`css` option', async t => { test('`script` option', async t => { const screenshots = await new Pageres({ script: 'document.body.style.backgroundColor = \'red\';', - }).src(server.url, ['1024x768']).run(); + }).source(server.url, ['1024x768']).run(); const pixels = await getPngPixels(screenshots[0]); t.is(pixels[0], 255); t.is(pixels[1], 0); @@ -167,7 +159,7 @@ test('`script` option', async t => { test('`filename` option', async t => { const screenshots = await new Pageres() - .src(server.url, ['1024x768'], { + .source(server.url, ['1024x768'], { filename: '<%= date %> - <%= time %> - <%= url %>', }) .run(); @@ -177,7 +169,7 @@ test('`filename` option', async t => { }); test('`selector` option', async t => { - const screenshots = await new Pageres({selector: '#team'}).src(server.url, ['1024x768']).run(); + const screenshots = await new Pageres({selector: '#team'}).source(server.url, ['1024x768']).run(); t.is(screenshots[0].filename, `${server.host}!${server.port}-1024x768.png`); const size = imageSize(screenshots[0]) as any; @@ -188,27 +180,27 @@ test('`selector` option', async t => { test.serial('support local relative files', async t => { const _cwd = process.cwd(); process.chdir(__dirname); - const screenshots = await new Pageres().src('fixture.html', ['1024x768']).run(); + const screenshots = await new Pageres().source('fixture.html', ['1024x768']).run(); t.is(screenshots[0].filename, 'fixture.html-1024x768.png'); t.true(screenshots[0].length > 1000); process.chdir(_cwd); }); test('support local absolute files', async t => { - const screenshots = await new Pageres().src(path.join(__dirname, 'fixture.html'), ['1024x768']).run(); + const screenshots = await new Pageres().source(path.join(__dirname, 'fixture.html'), ['1024x768']).run(); t.is(screenshots[0].filename, 'fixture.html-1024x768.png'); t.true(screenshots[0].length > 1000); }); /// test('fetch resolutions from w3counter', async t => { -// const screenshots = await new Pageres().src(server.url, ['w3counter']).run(); +// const screenshots = await new Pageres().source(server.url, ['w3counter']).run(); // t.is(screenshots.length, 10); // t.true(screenshots[0].length > 1000); // }); test('save image', async t => { try { - await new Pageres().src(server.url, ['1024x768']).dest(__dirname).run(); + await new Pageres().source(server.url, ['1024x768']).destination(__dirname).run(); t.true(fs.existsSync(path.join(__dirname, `${server.host}!${server.port}-1024x768.png`))); } finally { await fsPromises.unlink(path.join(__dirname, `${server.host}!${server.port}-1024x768.png`)); @@ -217,7 +209,7 @@ test('save image', async t => { test('remove temporary files on error', async t => { await t.throwsAsync( - new Pageres().src('https://this-is-a-error-site.io', ['1024x768']).dest(__dirname).run(), + new Pageres().source('https://this-is-a-error-site.io', ['1024x768']).destination(__dirname).run(), { message: /ERR_NAME_NOT_RESOLVED/, }, @@ -229,7 +221,7 @@ test('auth using username and password', async t => { const screenshots = await new Pageres({ username: 'user', password: 'passwd', - }).src('https://httpbin.org/basic-auth/user/passwd', ['120x120']).run(); + }).source('https://httpbin.org/basic-auth/user/passwd', ['120x120']).run(); t.is(screenshots.length, 1); t.true(screenshots[0].length > 0); @@ -239,7 +231,7 @@ test('`scale` option', async t => { const screenshots = await new Pageres({ scale: 2, crop: true, - }).src(server.url, ['120x120']).run(); + }).source(server.url, ['120x120']).run(); const size = imageSize(screenshots[0]) as any; t.is(size.width, 240); @@ -247,13 +239,13 @@ test('`scale` option', async t => { }); test('support data URL', async t => { - const screenshots = await new Pageres().src('data:text/html;base64,PGgxPkZPTzwvaDE+', ['100x100']).run(); + const screenshots = await new Pageres().source('data:text/html;base64,PGgxPkZPTzwvaDE+', ['100x100']).run(); const fileType = await fileTypeFromBuffer(screenshots[0]); t.is(fileType?.mime, 'image/png'); }); test('`format` option', async t => { - const screenshots = await new Pageres().src(server.url, ['100x100'], {format: 'jpg'}).run(); + const screenshots = await new Pageres().source(server.url, ['100x100'], {format: 'jpg'}).run(); const fileType = await fileTypeFromBuffer(screenshots[0]); t.is(fileType?.mime, 'image/jpeg'); }); @@ -261,9 +253,9 @@ test('`format` option', async t => { test('when a file exists, append an incrementer', async t => { const folderPath = process.cwd(); try { - await new Pageres({delay: 2}).src(server.url, ['1024x768', '480x320'], {incrementalName: true, filename: '<%= url %>'}).dest(folderPath).run(); + await new Pageres({delay: 2}).source(server.url, ['1024x768', '480x320'], {incrementalName: true, filename: '<%= url %>'}).destination(folderPath).run(); t.true(fs.existsSync(path.join(folderPath, `${serverFileName}.png`))); - await new Pageres({delay: 2}).src(server.url, ['1024x768', '480x320'], {incrementalName: true, filename: '<%= url %>'}).dest(folderPath).run(); + await new Pageres({delay: 2}).source(server.url, ['1024x768', '480x320'], {incrementalName: true, filename: '<%= url %>'}).destination(folderPath).run(); t.true(fs.existsSync(path.join(folderPath, `${serverFileName} (1).png`))); } finally { await fsPromises.unlink(path.join(folderPath, `${serverFileName}.png`));