Skip to content

Commit

Permalink
test: more robust PDF specs
Browse files Browse the repository at this point in the history
  • Loading branch information
codebytere committed Oct 11, 2022
1 parent 7493062 commit 4c389c7
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 25 deletions.
119 changes: 94 additions & 25 deletions spec/api-web-contents-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1911,9 +1911,13 @@ describe('webContents module', () => {
ifdescribe(features.isPrintingEnabled())('printToPDF()', () => {
let w: BrowserWindow;

beforeEach(async () => {
w = new BrowserWindow({ show: false, webPreferences: { sandbox: true } });
await w.loadURL('data:text/html,<h1>Hello, World!</h1>');
beforeEach(() => {
w = new BrowserWindow({
show: false,
webPreferences: {
sandbox: true
}
});
});

afterEach(closeAllWindows);
Expand All @@ -1932,19 +1936,18 @@ describe('webContents module', () => {
preferCSSPageSize: 'no'
};

await w.loadURL('data:text/html,<h1>Hello, World!</h1>');

// These will hard crash in Chromium unless we type-check
for (const [key, value] of Object.entries(badTypes)) {
const param = { [key]: value };
await expect(w.webContents.printToPDF(param)).to.eventually.be.rejected();
}
});

it('can print to PDF', async () => {
const data = await w.webContents.printToPDF({});
expect(data).to.be.an.instanceof(Buffer).that.is.not.empty();
});

it('does not crash when called multiple times in parallel', async () => {
await w.loadURL('data:text/html,<h1>Hello, World!</h1>');

const promises = [];
for (let i = 0; i < 3; i++) {
promises.push(w.webContents.printToPDF({}));
Expand All @@ -1957,6 +1960,8 @@ describe('webContents module', () => {
});

it('does not crash when called multiple times in sequence', async () => {
await w.loadURL('data:text/html,<h1>Hello, World!</h1>');

const results = [];
for (let i = 0; i < 3; i++) {
const result = await w.webContents.printToPDF({});
Expand All @@ -1968,30 +1973,94 @@ describe('webContents module', () => {
}
});

describe('using a large document', () => {
beforeEach(async () => {
w = new BrowserWindow({ show: false, webPreferences: { sandbox: true } });
await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf.html'));
});
it('can print a PDF with default settings', async () => {
await w.loadURL('data:text/html,<h1>Hello, World!</h1>');

afterEach(closeAllWindows);
const data = await w.webContents.printToPDF({});
expect(data).to.be.an.instanceof(Buffer).that.is.not.empty();
});

it('respects custom settings', async () => {
const data = await w.webContents.printToPDF({
pageRanges: '1-3',
landscape: true
});
it('with custom page sizes', async () => {
const paperFormats: Record<string, ElectronInternal.PageSize> = {
letter: { width: 8.5, height: 11 },
legal: { width: 8.5, height: 14 },
tabloid: { width: 11, height: 17 },
ledger: { width: 17, height: 11 },
a0: { width: 33.1, height: 46.8 },
a1: { width: 23.4, height: 33.1 },
a2: { width: 16.54, height: 23.4 },
a3: { width: 11.7, height: 16.54 },
a4: { width: 8.27, height: 11.7 },
a5: { width: 5.83, height: 8.27 },
a6: { width: 4.13, height: 5.83 }
};

await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf-small.html'));

for (const format of Object.keys(paperFormats)) {
const data = await w.webContents.printToPDF({ pageSize: format });

const doc = await pdfjs.getDocument(data).promise;
const page = await doc.getPage(1);

// page.view is [top, left, width, height].
const width = page.view[2] / 72;
const height = page.view[3] / 72;

const approxEq = (a: number, b: number, epsilon = 0.01) => Math.abs(a - b) <= epsilon;

expect(approxEq(width, paperFormats[format].width)).to.be.true();
expect(approxEq(height, paperFormats[format].height)).to.be.true();
}
});

it('with custom header and footer', async () => {
await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf-small.html'));

const data = await w.webContents.printToPDF({
displayHeaderFooter: true,
headerTemplate: '<div>I\'m a PDF header</div>',
footerTemplate: '<div>I\'m a PDF footer</div>'
});

// Check that correct # of pages are rendered.
expect(doc.numPages).to.equal(3);
const doc = await pdfjs.getDocument(data).promise;
const page = await doc.getPage(1);

// Check that PDF is generated in landscape mode.
const firstPage = await doc.getPage(1);
const { width, height } = firstPage.getViewport({ scale: 100 });
expect(width).to.be.greaterThan(height);
const { items } = await page.getTextContent();

// Check that generated PDF contains a header.
const containsText = (text: RegExp) => items.some(({ str }: { str: string }) => str.match(text));

expect(containsText(/I'm a PDF header/)).to.be.true();
expect(containsText(/I'm a PDF footer/)).to.be.true();
});

it('in landscape mode', async () => {
await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf-small.html'));

const data = await w.webContents.printToPDF({ landscape: true });
const doc = await pdfjs.getDocument(data).promise;
const page = await doc.getPage(1);

// page.view is [top, left, width, height].
const width = page.view[2];
const height = page.view[3];

expect(width).to.be.greaterThan(height);
});

it('with custom page ranges', async () => {
await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf-large.html'));

const data = await w.webContents.printToPDF({
pageRanges: '1-3',
landscape: true
});

const doc = await pdfjs.getDocument(data).promise;

// Check that correct # of pages are rendered.
expect(doc.numPages).to.equal(3);
});
});

Expand Down
File renamed without changes.
17 changes: 17 additions & 0 deletions spec/fixtures/api/print-to-pdf-small.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<html>
<head>
<title>Your Title Here</title>
</head>

<body style="background: green;">
<h1>This is a header</h1>
<h2>This is a Medium header</h2>

Send me mail at <a href="mailto:support@yourcompany.com">support@yourcompany.com</a>.

<p> This is a new paragraph!
<p> <b>This is a new paragraph!</b>
<br> <b><i>This is a new sentence without a paragraph break, in bold italics.</i></b>
</body>

</html>

0 comments on commit 4c389c7

Please sign in to comment.