diff --git a/src/core/document.js b/src/core/document.js index 57167a8945ac0..439256d83c952 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -1038,10 +1038,11 @@ class PDFDocument { "hasJSActions", this.fieldObjects.then(fieldObjects => { return ( - fieldObjects !== null && - Object.values(fieldObjects).some(fieldObject => - fieldObject.some(object => object.actions !== null) - ) + (fieldObjects !== null && + Object.values(fieldObjects).some(fieldObject => + fieldObject.some(object => object.actions !== null) + )) || + !!this.catalog.jsActions ); }) ); diff --git a/test/integration/scripting_spec.js b/test/integration/scripting_spec.js index 923c7dded5580..8e5796945ba8f 100644 --- a/test/integration/scripting_spec.js +++ b/test/integration/scripting_spec.js @@ -16,6 +16,15 @@ const { clearInput, closePages, loadAndWait } = require("./test_utils.js"); describe("Interaction", () => { + async function actAndWaitForInput(page, selector, action) { + await clearInput(page, selector); + await action(); + await page.waitForFunction( + `document.querySelector("${selector.replace("\\", "\\\\")}").value !== ""` + ); + return page.$eval(selector, el => el.value); + } + describe("in 160F-2019.pdf", () => { let pages; @@ -280,4 +289,76 @@ describe("Interaction", () => { ); }); }); + + describe("in doc_actions.pdf for printing", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait("doc_actions.pdf", "#\\34 7R"); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must execute WillPrint and DidPrint actions", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + if (process.platform === "win32" && browserName === "firefox") { + // Doesn't work because of bug 1662471 + return; + } + let text = await actAndWaitForInput(page, "#\\34 7R", async () => { + await page.click("#print"); + }); + expect(text).withContext(`In ${browserName}`).toEqual("WillPrint"); + + await page.waitForFunction( + `document.querySelector("#\\\\35 0R").value !== ""` + ); + + text = await page.$eval("#\\35 0R", el => el.value); + expect(text).withContext(`In ${browserName}`).toEqual("DidPrint"); + }) + ); + }); + }); + + describe("in doc_actions.pdf for saving", () => { + let pages; + + beforeAll(async () => { + pages = await loadAndWait("doc_actions.pdf", "#\\34 7R"); + }); + + afterAll(async () => { + await closePages(pages); + }); + + it("must execute WillSave and DidSave actions", async () => { + await Promise.all( + pages.map(async ([browserName, page]) => { + try { + // Disable download in chrome + // (it leads to an error in firefox so the try...) + await page._client.send("Page.setDownloadBehavior", { + behavior: "deny", + }); + } catch (_) {} + await clearInput(page, "#\\34 7R"); + let text = await actAndWaitForInput(page, "#\\34 7R", async () => { + await page.click("#download"); + }); + expect(text).withContext(`In ${browserName}`).toEqual("WillSave"); + + await page.waitForFunction( + `document.querySelector("#\\\\35 0R").value !== ""` + ); + + text = await page.$eval("#\\35 0R", el => el.value); + expect(text).withContext(`In ${browserName}`).toEqual("DidSave"); + }) + ); + }); + }); }); diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 8d5894dee1320..b81f2b0f68541 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -46,6 +46,7 @@ !issue7544.pdf !issue7507.pdf !issue6931_reduced.pdf +!doc_actions.pdf !issue7580.pdf !issue7598.pdf !issue12750.pdf @@ -179,7 +180,6 @@ !pattern_text_embedded_font.pdf !devicen.pdf !cmykjpeg.pdf -!docactions.pdf !issue840.pdf !160F-2019.pdf !issue4402_reduced.pdf diff --git a/test/pdfs/doc_actions.pdf b/test/pdfs/doc_actions.pdf new file mode 100644 index 0000000000000..bcc3ed923f484 Binary files /dev/null and b/test/pdfs/doc_actions.pdf differ diff --git a/test/pdfs/docactions.pdf b/test/pdfs/docactions.pdf deleted file mode 100644 index 56381f322ad82..0000000000000 Binary files a/test/pdfs/docactions.pdf and /dev/null differ diff --git a/test/test.js b/test/test.js index 63e2a5be5d06f..374fddf3537e7 100644 --- a/test/test.js +++ b/test/test.js @@ -836,15 +836,36 @@ async function startBrowser(browserName, startUrl = "") { ignoreDefaultArgs: ["--disable-extensions"], }; + if (!tempDir) { + tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pdfjs-")); + } + const printFile = path.join(tempDir, "print.pdf"); + if (browserName === "chrome") { // avoid crash options.args = ["--no-sandbox", "--disable-setuid-sandbox"]; + // silent printing in a pdf + options.args.push("--kiosk-printing"); } if (browserName === "firefox") { options.extraPrefsFirefox = { // avoid to have a prompt when leaving a page with a form "dom.disable_beforeunload": true, + // Disable dialog when saving a pdf + "pdfjs.disabled": true, + "browser.helperApps.neverAsk.saveToDisk": "application/pdf", + // Avoid popup when saving is done + "browser.download.panel.shown": true, + // Save file in output + "browser.download.folderList": 2, + "browser.download.dir": tempDir, + // Print silently in a pdf + "print.always_print_silent": true, + "print.show_print_progress": false, + print_printer: "PDF", + "print.printer_PDF.print_to_file": true, + "print.printer_PDF.print_to_filename": printFile, }; } @@ -928,8 +949,15 @@ async function closeSession(browser) { const allClosed = sessions.every(function (s) { return s.closed; }); - if (allClosed && onAllSessionsClosed) { - onAllSessionsClosed(); + if (allClosed) { + if (tempDir) { + const rimraf = require("rimraf"); + rimraf.sync(tempDir); + } + + if (onAllSessionsClosed) { + onAllSessionsClosed(); + } } } } @@ -984,5 +1012,6 @@ var onAllSessionsClosed; var host = "127.0.0.1"; var options = parseOptions(); var stats; +var tempDir = null; main(); diff --git a/test/test_manifest.json b/test/test_manifest.json index 2996c1b41c761..f5c1b0d5dfdb6 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -894,12 +894,6 @@ "link": false, "type": "eq" }, - { "id": "docactions", - "file": "pdfs/docactions.pdf", - "md5": "28ea940349cf7cb793cfe167d04b097c", - "rounds": 1, - "type": "eq" - }, { "id": "issue9084", "file": "pdfs/issue9084.pdf", "md5": "5570ec01cc869d299fec1b2f68926a08", @@ -1450,6 +1444,12 @@ "type": "eq", "about": "Type3 fonts with image resources; both pages need to be tested, otherwise the bug won't manifest." }, + { "id": "doc_actions", + "file": "pdfs/doc_actions.pdf", + "md5": "ceae4eb405a0b40394f4d63d7525a870", + "rounds": 1, + "type": "eq" + }, { "id": "issue12504", "file": "pdfs/issue12504.pdf", "md5": "04fcc87f3e7e9e925e3ef83cf0bf49f4", diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index 82e3b1034087b..5cb6dbc546ba3 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -1006,27 +1006,33 @@ describe("api", function () { }); it("gets JSActions", function (done) { // PDF document with "JavaScript" action in the OpenAction dictionary. - const loadingTask = getDocument(buildGetDocumentParams("docactions.pdf")); + const loadingTask = getDocument( + buildGetDocumentParams("doc_actions.pdf") + ); const promise = loadingTask.promise.then(async pdfDoc => { const docActions = await pdfDoc.getJSActions(); - const page5 = await pdfDoc.getPage(5); - const page12 = await pdfDoc.getPage(12); - const page5Actions = await page5.getJSActions(); - const page12Actions = await page12.getJSActions(); - return [docActions, page5Actions, page12Actions]; + const page1 = await pdfDoc.getPage(1); + const page3 = await pdfDoc.getPage(3); + const page1Actions = await page1.getJSActions(); + const page3Actions = await page3.getJSActions(); + return [docActions, page1Actions, page3Actions]; }); promise - .then(async ([docActions, page5Actions, page12Actions]) => { + .then(async ([docActions, page1Actions, page3Actions]) => { expect(docActions).toEqual({ - Open: ["console.println('Open Action');"], + DidPrint: [`this.getField("Text2").value = "DidPrint";`], + DidSave: [`this.getField("Text2").value = "DidSave";`], + WillClose: [`this.getField("Text1").value = "WillClose";`], + WillPrint: [`this.getField("Text1").value = "WillPrint";`], + WillSave: [`this.getField("Text1").value = "WillSave";`], }); - expect(page5Actions).toEqual({ - PageOpen: ["console.println('Open page 5');"], - PageClose: ["console.println('Close page 5');"], + expect(page1Actions).toEqual({ + PageOpen: [`this.getField("Text1").value = "PageOpen 1";`], + PageClose: [`this.getField("Text2").value = "PageClose 1";`], }); - expect(page12Actions).toEqual({ - PageOpen: ["console.println('Open page 12');"], - PageClose: ["console.println('Close page 12');"], + expect(page3Actions).toEqual({ + PageOpen: [`this.getField("Text5").value = "PageOpen 3";`], + PageClose: [`this.getField("Text6").value = "PageClose 3";`], }); loadingTask.destroy().then(done); })