From 786ad509b89b882846fb5bcbb30cee72c8fb1875 Mon Sep 17 00:00:00 2001 From: Bayheck Date: Sun, 26 Nov 2023 18:57:44 +0600 Subject: [PATCH 1/4] fix: upload files with required inputs in native automation --- src/client/automation/playback/upload.js | 26 +++++++++++++++++-- .../action-executor/actions-initializer.ts | 3 ++- .../api/es-next/upload/pages/index.html | 24 ++++++++++------- .../fixtures/api/es-next/upload/test.js | 4 +++ .../upload/testcafe-fixtures/upload-test.js | 8 ++++++ 5 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/client/automation/playback/upload.js b/src/client/automation/playback/upload.js index 961ad2413e3..a6c115d1209 100644 --- a/src/client/automation/playback/upload.js +++ b/src/client/automation/playback/upload.js @@ -1,12 +1,34 @@ -import { doUpload } from '../deps/hammerhead'; +import { + doUpload, eventSandbox, nativeMethods, +} from '../deps/hammerhead'; import { arrayUtils } from '../deps/testcafe-core'; export default class UploadAutomation { - constructor (element, paths, createError) { + constructor (element, paths, createError, isNativeAutomation) { this.element = element; this.paths = paths; this.createError = createError; + + if (isNativeAutomation) + this._handleRequiredInput(); + } + + _handleRequiredInput () { + const isRequired = nativeMethods.hasAttribute.call(this.element, 'required'); + + if (isRequired) + nativeMethods.removeAttribute.call(this.element, 'required'); + + const ensureUploadInputHasRequiredAttribute = () => { + if (isRequired) + nativeMethods.setAttribute.call(this.element, 'required', 'true'); + }; + + if (this.element.form) { + eventSandbox.listeners.initElementListening(this.element.form, ['submit']); + eventSandbox.listeners.addInternalEventAfterListener(this.element.form, ['submit'], ensureUploadInputHasRequiredAttribute); + } } run () { diff --git a/src/client/driver/command-executors/action-executor/actions-initializer.ts b/src/client/driver/command-executors/action-executor/actions-initializer.ts index e94fae0e1e0..18f8c152fc3 100644 --- a/src/client/driver/command-executors/action-executor/actions-initializer.ts +++ b/src/client/driver/command-executors/action-executor/actions-initializer.ts @@ -177,9 +177,10 @@ function ensureFileInput (element: Node[]): never | void { } ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.setFilesToUpload] = { - create: (command, elements) => { + create: (command, elements, dispatchNativeAutomationEventFn) => { return new UploadAutomation(elements[0], command.filePath, (filePaths: string[], scannedFilePaths: string[]) => new ActionCannotFindFileToUploadError(filePaths, scannedFilePaths), + dispatchNativeAutomationEventFn ); }, diff --git a/test/functional/fixtures/api/es-next/upload/pages/index.html b/test/functional/fixtures/api/es-next/upload/pages/index.html index 899fe7feff4..f5678b2e96e 100644 --- a/test/functional/fixtures/api/es-next/upload/pages/index.html +++ b/test/functional/fixtures/api/es-next/upload/pages/index.html @@ -1,13 +1,17 @@ - - - Upload - - -
- - -
- + + + Upload + + +
+ + +
+
+ + +
+ diff --git a/test/functional/fixtures/api/es-next/upload/test.js b/test/functional/fixtures/api/es-next/upload/test.js index 5f1fa346588..0a829b030c9 100644 --- a/test/functional/fixtures/api/es-next/upload/test.js +++ b/test/functional/fixtures/api/es-next/upload/test.js @@ -7,6 +7,10 @@ describe('[API] Upload', function () { return runTests('./testcafe-fixtures/upload-test.js', 'Upload the file', { only: 'chrome' }); }); + it('Should upload the specified file with required input', function () { + return runTests('./testcafe-fixtures/upload-test.js', 'Upload the file with required input', { only: 'chrome' }); + }); + it('Should validate the selector argument', function () { return runTests('./testcafe-fixtures/upload-test.js', 'Invalid selector argument (setFilesToUpload)', { shouldFail: true, diff --git a/test/functional/fixtures/api/es-next/upload/testcafe-fixtures/upload-test.js b/test/functional/fixtures/api/es-next/upload/testcafe-fixtures/upload-test.js index 9f188fbff6e..1434fca3201 100644 --- a/test/functional/fixtures/api/es-next/upload/testcafe-fixtures/upload-test.js +++ b/test/functional/fixtures/api/es-next/upload/testcafe-fixtures/upload-test.js @@ -15,6 +15,14 @@ test('Upload the file', async t => { expect(await getUploadedText()).equals('File 1 is uploaded!'); }); +test('Upload the file with required input', async t => { + await t + .setFilesToUpload('#fileTwo', '../test-data/file1.txt') + .click('#submitTwo'); + + expect(await getUploadedText()).equals('File 1 is uploaded!'); +}); + test('Clear the upload', async t => { await t .setFilesToUpload('#file', '../test-data/file1.txt') From c53db9b332b9a1ec9ea73db9ed949dea24439edd Mon Sep 17 00:00:00 2001 From: Bayheck Date: Sun, 26 Nov 2023 20:50:15 +0600 Subject: [PATCH 2/4] fix: validation tests failing fixed --- .../upload/testcafe-fixtures/upload-test.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/functional/fixtures/api/es-next/upload/testcafe-fixtures/upload-test.js b/test/functional/fixtures/api/es-next/upload/testcafe-fixtures/upload-test.js index 1434fca3201..aae0c9e9d6b 100644 --- a/test/functional/fixtures/api/es-next/upload/testcafe-fixtures/upload-test.js +++ b/test/functional/fixtures/api/es-next/upload/testcafe-fixtures/upload-test.js @@ -15,14 +15,6 @@ test('Upload the file', async t => { expect(await getUploadedText()).equals('File 1 is uploaded!'); }); -test('Upload the file with required input', async t => { - await t - .setFilesToUpload('#fileTwo', '../test-data/file1.txt') - .click('#submitTwo'); - - expect(await getUploadedText()).equals('File 1 is uploaded!'); -}); - test('Clear the upload', async t => { await t .setFilesToUpload('#file', '../test-data/file1.txt') @@ -47,3 +39,11 @@ test('Invalid selector argument (clearUpload)', async t => { test('Error on upload non-existing file', async t => { await t.setFilesToUpload('#file', ['../dummy-file-1.txt', '../dummy-file-2.txt']); }); + +test('Upload the file with required input', async t => { + await t + .setFilesToUpload('#fileTwo', '../test-data/file1.txt') + .click('#submitTwo'); + + expect(await getUploadedText()).equals('File 1 is uploaded!'); +}); From 473692e142fc8d026386e36a74118b44f735e090 Mon Sep 17 00:00:00 2001 From: Bayheck Date: Tue, 28 Nov 2023 14:13:27 +0600 Subject: [PATCH 3/4] fix: pr comments fixed --- src/client/automation/playback/upload.js | 13 ++++++++----- .../fixtures/api/es-next/upload/pages/index.html | 4 ++-- .../es-next/upload/testcafe-fixtures/upload-test.js | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/client/automation/playback/upload.js b/src/client/automation/playback/upload.js index a6c115d1209..9e6dfe8bfaa 100644 --- a/src/client/automation/playback/upload.js +++ b/src/client/automation/playback/upload.js @@ -4,6 +4,9 @@ import { import { arrayUtils } from '../deps/testcafe-core'; +const REQUIRED_ATTR_NAME = 'required'; +const FORM_SUBMIT_EVENT_NAME = 'submit'; + export default class UploadAutomation { constructor (element, paths, createError, isNativeAutomation) { this.element = element; @@ -15,19 +18,19 @@ export default class UploadAutomation { } _handleRequiredInput () { - const isRequired = nativeMethods.hasAttribute.call(this.element, 'required'); + const isRequired = nativeMethods.hasAttribute.call(this.element, REQUIRED_ATTR_NAME); if (isRequired) - nativeMethods.removeAttribute.call(this.element, 'required'); + nativeMethods.removeAttribute.call(this.element, REQUIRED_ATTR_NAME); const ensureUploadInputHasRequiredAttribute = () => { if (isRequired) - nativeMethods.setAttribute.call(this.element, 'required', 'true'); + nativeMethods.setAttribute.call(this.element, REQUIRED_ATTR_NAME, 'true'); }; if (this.element.form) { - eventSandbox.listeners.initElementListening(this.element.form, ['submit']); - eventSandbox.listeners.addInternalEventAfterListener(this.element.form, ['submit'], ensureUploadInputHasRequiredAttribute); + eventSandbox.listeners.initElementListening(this.element.form, [FORM_SUBMIT_EVENT_NAME]); + eventSandbox.listeners.addInternalEventAfterListener(this.element.form, [FORM_SUBMIT_EVENT_NAME], ensureUploadInputHasRequiredAttribute); } } diff --git a/test/functional/fixtures/api/es-next/upload/pages/index.html b/test/functional/fixtures/api/es-next/upload/pages/index.html index f5678b2e96e..59dde8caf51 100644 --- a/test/functional/fixtures/api/es-next/upload/pages/index.html +++ b/test/functional/fixtures/api/es-next/upload/pages/index.html @@ -10,8 +10,8 @@
- - + +
diff --git a/test/functional/fixtures/api/es-next/upload/testcafe-fixtures/upload-test.js b/test/functional/fixtures/api/es-next/upload/testcafe-fixtures/upload-test.js index aae0c9e9d6b..330a6d2f624 100644 --- a/test/functional/fixtures/api/es-next/upload/testcafe-fixtures/upload-test.js +++ b/test/functional/fixtures/api/es-next/upload/testcafe-fixtures/upload-test.js @@ -42,8 +42,8 @@ test('Error on upload non-existing file', async t => { test('Upload the file with required input', async t => { await t - .setFilesToUpload('#fileTwo', '../test-data/file1.txt') - .click('#submitTwo'); + .setFilesToUpload('#fileRequired', '../test-data/file1.txt') + .click('#submitRequired'); expect(await getUploadedText()).equals('File 1 is uploaded!'); }); From b979d4c137c480f4547e9f1bee854fedeff7fe0d Mon Sep 17 00:00:00 2001 From: Bayheck Date: Wed, 29 Nov 2023 12:48:49 +0600 Subject: [PATCH 4/4] fix: pr comments fixed --- src/client/automation/playback/upload.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client/automation/playback/upload.js b/src/client/automation/playback/upload.js index 9e6dfe8bfaa..487a134147b 100644 --- a/src/client/automation/playback/upload.js +++ b/src/client/automation/playback/upload.js @@ -1,5 +1,7 @@ import { - doUpload, eventSandbox, nativeMethods, + doUpload, + eventSandbox, + nativeMethods, } from '../deps/hammerhead'; import { arrayUtils } from '../deps/testcafe-core'; @@ -13,7 +15,7 @@ export default class UploadAutomation { this.paths = paths; this.createError = createError; - if (isNativeAutomation) + if (isNativeAutomation && this.element.form) this._handleRequiredInput(); } @@ -28,10 +30,8 @@ export default class UploadAutomation { nativeMethods.setAttribute.call(this.element, REQUIRED_ATTR_NAME, 'true'); }; - if (this.element.form) { - eventSandbox.listeners.initElementListening(this.element.form, [FORM_SUBMIT_EVENT_NAME]); - eventSandbox.listeners.addInternalEventAfterListener(this.element.form, [FORM_SUBMIT_EVENT_NAME], ensureUploadInputHasRequiredAttribute); - } + eventSandbox.listeners.initElementListening(this.element.form, [FORM_SUBMIT_EVENT_NAME]); + eventSandbox.listeners.addInternalEventAfterListener(this.element.form, [FORM_SUBMIT_EVENT_NAME], ensureUploadInputHasRequiredAttribute); } run () {