diff --git a/acrobat/blocks/verb-widget/icons.js b/acrobat/blocks/verb-widget/icons.js
index bf90dfc1..460dbbb7 100644
--- a/acrobat/blocks/verb-widget/icons.js
+++ b/acrobat/blocks/verb-widget/icons.js
@@ -4,6 +4,7 @@
const ICONS = {
WIDGET_ICON: '',
fillsign: '',
+ 'compress-pdf': '',
UPLOAD_ICON: '',
SECURITY_ICON: '',
INFO_ICON: '',
diff --git a/acrobat/blocks/verb-widget/limits.js b/acrobat/blocks/verb-widget/limits.js
index 4457b30b..f9436f94 100644
--- a/acrobat/blocks/verb-widget/limits.js
+++ b/acrobat/blocks/verb-widget/limits.js
@@ -1,25 +1,37 @@
const LIMITS = {
fillsign: {
- maxFileSize: 100000000, // 100 MB
+ maxFileSize: 104857600, // 100 MB
maxFileSizeFriendly: '100 MB', // 100 MB
- acceptedFiles: '.pdf',
+ acceptedFiles: ['application/pdf'],
maxNumFiles: 1,
+ multipleFiles: false,
mobileApp: true,
},
'delete-pages': {
maxFileSize: 100000000, // 1 MB
- acceptedFiles: '.pdf',
+ acceptedFiles: ['application/pdf'],
maxNumFiles: 1,
},
'number-pages': {
maxFileSize: 100000000, // 1 MB
- acceptedFiles: '.pdf',
+ acceptedFiles: ['application/pdf'],
maxNumFiles: 1,
},
'compress-pdf': {
- maxFileSize: 100000000,
- acceptedFiles: '.pdf',
- maxNumFiles: 1,
+ maxFileSize: 2147483648,
+ maxFileSizeFriendly: '2 GB',
+ acceptedFiles: [
+ 'application/pdf',
+ 'application/msword',
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'application/vnd.ms-powerpoint',
+ 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+ 'application/vnd.ms-excel',
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'image/jpeg',
+ 'image/png',
+ ],
+ multipleFiles: true,
},
};
diff --git a/acrobat/blocks/verb-widget/verb-widget.js b/acrobat/blocks/verb-widget/verb-widget.js
index 9a36104a..1ccf9104 100644
--- a/acrobat/blocks/verb-widget/verb-widget.js
+++ b/acrobat/blocks/verb-widget/verb-widget.js
@@ -133,7 +133,14 @@ export default async function init(element) {
}
const widgetMobileButton = createTag('a', { class: 'verb-mobile-cta', href: mobileLink }, window.mph['verb-widget-cta-mobile']);
- const button = createTag('input', { type: 'file', accept: LIMITS[VERB].acceptedFiles, id: 'file-upload', class: 'hide', 'aria-hidden': true });
+ const button = createTag('input', {
+ type: 'file',
+ accept: LIMITS[VERB]?.acceptedFiles,
+ id: 'file-upload',
+ class: 'hide',
+ 'aria-hidden': true,
+ ...(LIMITS[VERB]?.multipleFiles && { multiple: '' }),
+ });
const widgetImage = createTag('div', { class: 'verb-image' });
const verbIconName = `${VERB}`;
const verbImageSvg = createSvgElement(verbIconName);
diff --git a/package-lock.json b/package-lock.json
index 929bcedd..f7b27588 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23,7 +23,7 @@
},
"devDependencies": {
"@amwp/platform-ui-automation": "^0.0.6",
- "@amwp/platform-ui-lib-adobe": "^0.0.7",
+ "@amwp/platform-ui-lib-adobe": "^0.0.9",
"@babel/core": "7.23.2",
"@babel/eslint-parser": "7.22.15",
"@babel/register": "7.22.15",
@@ -119,9 +119,9 @@
}
},
"node_modules/@amwp/platform-ui-lib-adobe": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/@amwp/platform-ui-lib-adobe/-/platform-ui-lib-adobe-0.0.7.tgz",
- "integrity": "sha512-5tF6QFLZIvGDS/thYanj2srt6NrSQ0lq34m9KzaPEIVfj2OywLLVoavDaxgJvmhTGywIGngMrXyDx+YIUIInyA==",
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/@amwp/platform-ui-lib-adobe/-/platform-ui-lib-adobe-0.0.9.tgz",
+ "integrity": "sha512-F/1En1XlUJMYxbpesvd0G64XDyO8xsLUGIyyoBs4YehcDVk7CbHRHVShs6U9LoQ7A4ElEb5KXK7W5YqtRWp+nw==",
"dev": true
},
"node_modules/@babel/code-frame": {
diff --git a/package.json b/package.json
index 3b3bd3c9..f4ce8a6e 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,7 @@
"homepage": "https://github.com/adobecom/dc#readme",
"devDependencies": {
"@amwp/platform-ui-automation": "^0.0.6",
- "@amwp/platform-ui-lib-adobe": "^0.0.7",
+ "@amwp/platform-ui-lib-adobe": "^0.0.9",
"@babel/core": "7.23.2",
"@babel/eslint-parser": "7.22.15",
"@babel/register": "7.22.15",
diff --git a/test/e2e/features/unity/verbs.feature b/test/e2e/features/unity/verbs.feature
new file mode 100644
index 00000000..2e5db0ce
--- /dev/null
+++ b/test/e2e/features/unity/verbs.feature
@@ -0,0 +1,26 @@
+Feature: Frictionless Converter Block
+
+ Background:
+ Given I have a new browser context
+
+ @smoke @unity @sign-pdf @choosefile
+ Scenario Outline: L1 Verb - Upload and sign-in
+ Given I go to the page
+ Then I choose the file "" to upload
+ Then I wait for 5 seconds
+ Then I should see the address bar contains "acrobat.adobe.com"
+
+ Examples:
+ | Verb | File |
+ | sign-pdf | test-files/test.pdf |
+
+ @smoke @unity @sign-pdf @dragndrop
+ Scenario Outline: L1 Verb - Upload and sign-in
+ Given I go to the page
+ Then I drag-and-drop the file "" to upload
+ Then I wait for 5 seconds
+ Then I should see the address bar contains "acrobat.adobe.com"
+
+ Examples:
+ | Verb | File |
+ | sign-pdf | test-files/test.pdf |
\ No newline at end of file
diff --git a/test/e2e/page-objects/unity.page.js b/test/e2e/page-objects/unity.page.js
new file mode 100644
index 00000000..31ebbe71
--- /dev/null
+++ b/test/e2e/page-objects/unity.page.js
@@ -0,0 +1,34 @@
+import { classes } from "polytype";
+import { DcGnavPage } from "./dcgnav.page";
+import { CaaSSection } from "./caas.section";
+import { VerbWidgetSection } from "./verbwidget.section";
+
+export class UnityPage extends classes(DcGnavPage, VerbWidgetSection, CaaSSection) {
+ constructor(contentPath) {
+ super({
+ super: DcGnavPage,
+ arguments: [contentPath],
+ });
+ this.buildProps({
+ howToDefault: 'div[data-path*="how-to/default"]',
+ howTo2ndConversion: '[data-tag="2nd conversion"] div[data-path*="how-to/2nd-conversion"]',
+ verbSubfooter: '.verb-subfooter',
+ reviewComponent: '.review',
+ reviewStats: '.hlx-ReviewStats',
+ reviewSubmitResponse: '.hlx-submitResponse',
+ reviewDisabled: '.hlx-Review-ratingFields[disabled]',
+ reviewCommentField: '.hlx-Review-commentFields textarea',
+ reviewCommentSubmit: '.hlx-Review-commentFields input[type="submit"]',
+ reviewInputField: 'fieldset.hlx-Review-ratingFields input',
+ signUp: '[href*="https://auth.services.adobe.com"][href*="signup"]',
+ extensionModal: '#chromeext, #edgeext',
+ closeExtensionModal: '#chromeext .dialog-close, #edgeext .dialog-close',
+ eventwrapperOnload: '.eventwrapper.onload',
+ previewDescription: 'div[class*="previewDescription"]',
+ });
+ }
+
+ reviewStartInput(rating) {
+ return this.native.locator(`.hlx-Review-ratingFields input[value="${rating}"]`);
+ }
+}
diff --git a/test/e2e/page-objects/verbwidget.section.js b/test/e2e/page-objects/verbwidget.section.js
new file mode 100644
index 00000000..8cfeee3f
--- /dev/null
+++ b/test/e2e/page-objects/verbwidget.section.js
@@ -0,0 +1,69 @@
+import fs from 'fs';
+import path from 'path';
+import { Section } from '@amwp/platform-ui-automation/lib/common/page-objects/section';
+
+export class VerbWidgetSection extends Section {
+ constructor() {
+ super();
+ this.buildProps({
+ selectButton: '.verb-cta',
+ fileUploadInput: '#file-upload',
+ dropZone: '#drop-zone',
+ })
+ }
+
+ async chooseFiles(filePaths) {
+ const fileChooserPromise = this.native.waitForEvent('filechooser');
+ this.selectButton.click();
+ const fileChooser = await fileChooserPromise;
+ await fileChooser.setFiles(filePaths);
+ }
+
+ async dragndropFiles(filePaths) {
+ const filePath = filePaths[0];
+ const buffer = fs.readFileSync(filePath).toString('base64');
+ const basename = path.basename(filePath);
+
+ const dataTransfer = await this.dropZone.evaluateHandle(async({bufferData, basename}) => {
+ const dt = new DataTransfer();
+ const blobData = await fetch(bufferData).then((res) => res.blob());
+ const file = new File([blobData], basename, { type: 'application/pdf' });
+ dt.items.add(file);
+ return dt;
+ }, {
+ bufferData: `data:application/octet-stream;base64,${buffer}`,
+ basename
+ });
+
+ await this.dropZone.dispatchEvent('drop', { dataTransfer });
+ }
+}
+
+async function dragAndDropFile(
+ page,
+ selector,
+ filePath,
+ fileName,
+ fileType = ''
+ ) {
+ const buffer = readFileSync(filePath).toString('base64');
+
+ const dataTransfer = await page.evaluateHandle(
+ async ({ bufferData, localFileName, localFileType }) => {
+ const dt = new DataTransfer();
+
+ const blobData = await fetch(bufferData).then((res) => res.blob());
+
+ const file = new File([blobData], localFileName, { type: localFileType });
+ dt.items.add(file);
+ return dt;
+ },
+ {
+ bufferData: `data:application/octet-stream;base64,${buffer}`,
+ localFileName: fileName,
+ localFileType: fileType,
+ }
+ );
+
+ await page.dispatchEvent(selector, 'drop', { dataTransfer });
+ };
\ No newline at end of file
diff --git a/test/e2e/step-definitions/dc.steps.js b/test/e2e/step-definitions/dc.steps.js
index a42ac101..8fe20c8e 100644
--- a/test/e2e/step-definitions/dc.steps.js
+++ b/test/e2e/step-definitions/dc.steps.js
@@ -23,6 +23,7 @@ import { MergePdfPage } from "../page-objects/mergepdf.page";
import { CompressPdfPage } from "../page-objects/compresspdf.page";
import { PasswordProtectPdfPage } from "../page-objects/passwordprotectpdf.page";
import { FrictionlessPage } from "../page-objects/frictionless.page";
+import { UnityPage } from "../page-objects/unity.page";
import { DCPage } from "../page-objects/dc.page";
import { cardinal } from "../support/cardinal";
import { expect } from "@playwright/test";
@@ -643,3 +644,45 @@ Then(/^I confirm phone number is different and has geo-ip value "([^"]*)"$/, asy
expect(this.phoneNumber).not.toEqual(geoIpPhoneNumber);
expect(geoIpPhoneNumber).toEqual(geoIpPhoneNumberValue);
})
+
+Then(/^I choose the (?:PDF|file|files) "([^\"]*)" to upload$/, async function (filePath) {
+ this.context(UnityPage);
+ const filePaths = filePath.split(",");
+ const absPaths = filePaths.map((x) =>
+ path.resolve(global.config.profile.site, x)
+ );
+ let retry = 3;
+ while (retry > 0) {
+ await expect(this.page.selectButton).toHaveCount(1, { timeout: 15000 });
+ await this.page.native.waitForTimeout(2000);
+ try {
+ await this.page.chooseFiles(absPaths);
+ await this.page.native.waitForTimeout(2000);
+ await expect(this.page.selectButton).toHaveCount(0, { timeout: 15000 });
+ retry = 0;
+ } catch {
+ retry--;
+ }
+ }
+});
+
+Then(/^I drag-and-drop the (?:PDF|file|files) "([^\"]*)" to upload$/, async function (filePath) {
+ this.context(UnityPage);
+ const filePaths = filePath.split(",");
+ const absPaths = filePaths.map((x) =>
+ path.resolve(global.config.profile.site, x)
+ );
+ let retry = 3;
+ while (retry > 0) {
+ await expect(this.page.selectButton).toHaveCount(1, { timeout: 15000 });
+ await this.page.native.waitForTimeout(2000);
+ try {
+ await this.page.dragndropFiles(absPaths);
+ await this.page.native.waitForTimeout(2000);
+ await expect(this.page.selectButton).toHaveCount(0, { timeout: 15000 });
+ retry = 0;
+ } catch {
+ retry--;
+ }
+ }
+});
\ No newline at end of file