Avoid headless mode in CI
This commit is contained in:
@@ -2,7 +2,7 @@ version: 2
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/node:10-browsers
|
- image: circleci/node:latest-browsers
|
||||||
|
|
||||||
working_directory: ~/repo
|
working_directory: ~/repo
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,7 @@
|
|||||||
"karma-mocha": "1.3.0",
|
"karma-mocha": "1.3.0",
|
||||||
"karma-sourcemap-loader": "^0.3.7",
|
"karma-sourcemap-loader": "^0.3.7",
|
||||||
"karma-webpack": "^4.0.0-rc.2",
|
"karma-webpack": "^4.0.0-rc.2",
|
||||||
|
"loglevelnext": "^3.0.0",
|
||||||
"marked": "0.5.1",
|
"marked": "0.5.1",
|
||||||
"mocha": "5.2.0",
|
"mocha": "5.2.0",
|
||||||
"mustache": "^3.0.0",
|
"mustache": "^3.0.0",
|
||||||
|
|||||||
+58
-11
@@ -10,14 +10,10 @@ const fs = require('fs');
|
|||||||
const fse = require('fs-extra');
|
const fse = require('fs-extra');
|
||||||
const pixelmatch = require('pixelmatch');
|
const pixelmatch = require('pixelmatch');
|
||||||
const yargs = require('yargs');
|
const yargs = require('yargs');
|
||||||
|
const log = require('loglevelnext');
|
||||||
|
|
||||||
const compiler = webpack(Object.assign({mode: 'development'}, config));
|
const compiler = webpack(Object.assign({mode: 'development'}, config));
|
||||||
|
|
||||||
const handler = middleware(compiler, {
|
|
||||||
lazy: true,
|
|
||||||
logLevel: 'error'
|
|
||||||
});
|
|
||||||
|
|
||||||
function getHref(entry) {
|
function getHref(entry) {
|
||||||
return path.dirname(entry).slice(1) + '/';
|
return path.dirname(entry).slice(1) + '/';
|
||||||
}
|
}
|
||||||
@@ -38,16 +34,24 @@ function notFound(res) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function serve(port) {
|
function serve(options) {
|
||||||
|
const handler = middleware(compiler, {
|
||||||
|
lazy: true,
|
||||||
|
logger: options.log,
|
||||||
|
stats: 'minimal'
|
||||||
|
});
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const server = http.createServer((req, res) => {
|
const server = http.createServer((req, res) => {
|
||||||
handler(req, res, notFound(res));
|
handler(req, res, notFound(res));
|
||||||
});
|
});
|
||||||
|
|
||||||
server.listen(port, err => {
|
server.listen(options.port, options.host, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
|
const address = server.address();
|
||||||
|
options.log.info(`test server listening http://${address.address}:${address.port}/`);
|
||||||
resolve(() => server.close());
|
resolve(() => server.close());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -126,7 +130,7 @@ async function renderPage(page, entry, options) {
|
|||||||
resolve();
|
resolve();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
await page.goto(`http://localhost:${options.port}${getHref(entry)}`, {waitUntil: 'networkidle0'});
|
await page.goto(`http://${options.host}:${options.port}${getHref(entry)}`, {waitUntil: 'networkidle0'});
|
||||||
await renderCalled;
|
await renderCalled;
|
||||||
await page.screenshot({path: getActualScreenshotPath(entry)});
|
await page.screenshot({path: getActualScreenshotPath(entry)});
|
||||||
}
|
}
|
||||||
@@ -155,11 +159,29 @@ async function renderEach(page, entries, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function render(entries, options) {
|
async function render(entries, options) {
|
||||||
const browser = await puppeteer.launch();
|
const browser = await puppeteer.launch({
|
||||||
|
args: options.puppeteerArgs,
|
||||||
|
headless: !process.env.CI
|
||||||
|
});
|
||||||
|
|
||||||
let fail = false;
|
let fail = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
|
page.on('error', err => {
|
||||||
|
options.log.error('page crash', err);
|
||||||
|
});
|
||||||
|
page.on('pageerror', err => {
|
||||||
|
options.log.error('uncaught exception', err);
|
||||||
|
});
|
||||||
|
page.on('console', message => {
|
||||||
|
const type = message.type();
|
||||||
|
if (options.log[type]) {
|
||||||
|
options.log[type](message.text());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
page.setDefaultNavigationTimeout(options.timeout);
|
||||||
await exposeRender(page);
|
await exposeRender(page);
|
||||||
await page.setViewport({width: 256, height: 256});
|
await page.setViewport({width: 256, height: 256});
|
||||||
fail = await renderEach(page, entries, options);
|
fail = await renderEach(page, entries, options);
|
||||||
@@ -173,7 +195,7 @@ async function render(entries, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function main(entries, options) {
|
async function main(entries, options) {
|
||||||
const done = await serve(options.port);
|
const done = await serve(options);
|
||||||
try {
|
try {
|
||||||
await render(entries, options);
|
await render(entries, options);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -188,13 +210,38 @@ if (require.main === module) {
|
|||||||
describe: 'Accept all screenshots as accepted',
|
describe: 'Accept all screenshots as accepted',
|
||||||
default: false
|
default: false
|
||||||
}).
|
}).
|
||||||
|
option('host', {
|
||||||
|
describe: 'The host for serving rendering cases',
|
||||||
|
default: '127.0.0.1'
|
||||||
|
}).
|
||||||
option('port', {
|
option('port', {
|
||||||
describe: 'The port for serving rendering cases',
|
describe: 'The port for serving rendering cases',
|
||||||
|
type: 'number',
|
||||||
default: 3000
|
default: 3000
|
||||||
}).
|
}).
|
||||||
|
option('timeout', {
|
||||||
|
describe: 'The timeout for loading pages (in milliseconds)',
|
||||||
|
type: 'number',
|
||||||
|
default: 60000
|
||||||
|
}).
|
||||||
|
option('log-level', {
|
||||||
|
describe: 'The level for logging',
|
||||||
|
choices: ['trace', 'debug', 'info', 'warn', 'error', 'silent'],
|
||||||
|
default: 'error'
|
||||||
|
}).
|
||||||
|
option('puppeteer-args', {
|
||||||
|
describe: 'Args of for puppeteer.launch()',
|
||||||
|
type: 'array',
|
||||||
|
default: process.env.CI ? ['--no-sandbox', '--disable-setuid-sandbox'] : []
|
||||||
|
}).
|
||||||
parse();
|
parse();
|
||||||
|
|
||||||
const entries = Object.keys(config.entry).map(key => config.entry[key]);
|
const entries = Object.keys(config.entry).map(key => config.entry[key]);
|
||||||
|
|
||||||
main(entries, options).catch(err => process.stderr.write(`${err.message}\n`, () => process.exit(1)));
|
options.log = log.create({name: 'rendering', level: options.logLevel});
|
||||||
|
|
||||||
|
main(entries, options).catch(err => {
|
||||||
|
options.log.error(err.message);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user