cypress icon indicating copy to clipboard operation
cypress copied to clipboard

selectFile() on WebKit

Open verdeimparat opened this issue 2 years ago • 5 comments

Current behavior

Hello everyone,

I am new to Cypress and I am doing some tryouts for file upload in my project by using the built in file upload feature of Cypress over WebKit.

"devDependencies": { "cypress": "^11.2.0", "playwright-webkit": "^1.28.0" },

I know that WebKit is experimental but I didn't find anything regarding that selectFile() is not supported yet. I want to mention that on Chrome and Firefox my tests are passing and files are successfully uploaded.

The error that I am getting is:

Timed out retrying after 10000ms: undefined is not an object (evaluating 'dataTransfer.items.add')

Desired behavior

It should upload the file on WebKit as is done on Chrome/Firefox.

Test code to reproduce

    it('File Upload using selectFile with select mode', () => {
        cy.visit('https://practice.automationbro.com/cart/')
        
        cy.get('input[type=file')
        .invoke('removeClass', 'file_input_hidden')
        .selectFile('cypress/fixtures/image.png')

        cy.get('input[value="Upload File"]').click()
        cy.get('#wfu_messageblock_header_1_label_1', { timeout: 10000})
        .should('contain', 'uploaded successfully')
      })

Cypress Version

11.2.0

Node version

v16.18.0

Operating System

Windows 10

Debug Logs

`at <unknown> (https://autom.qa.myresqsoftware.com/__cypress/runner/cypress_runner.js:136892:23)
    at forEach ([native code])
    at createDataTransfer (https://autom.qa.myresqsoftware.com/__cypress/runner/cypress_runner.js:136882:16)
    at onReady (https://autom.qa.myresqsoftware.com/__cypress/runner/cypress_runner.js:137174:50)
    at retryActionability (https://autom.qa.myresqsoftware.com/__cypress/runner/cypress_runner.js:133601:28)
From previous event:
    at  (https://autom.qa.myresqsoftware.com/__cypress/runner/cypress_runner.js:137158:82)`

Noticed in cypress_runner.js that it may come from here:

'const createDataTransfer = (files, eventTarget) => {
  // obtain a reference to the `targetWindow` so we can use the right instances of the `File` and `DataTransfer` classes
  const targetWindow = eventTarget[0].ownerDocument.defaultView || window;
  const dataTransfer = new targetWindow.DataTransfer();
  files.forEach(({
    contents,
    fileName = '',
    mimeType = mime_types__WEBPACK_IMPORTED_MODULE_2___default.a.lookup(fileName) || '',
    lastModified = Date.now()
  }) => {
    const file = new targetWindow.File([contents], fileName, {
      lastModified,
      type: mimeType
    });
    dataTransfer.items.add(file);
  });
  const oldItems = dataTransfer.items; // dataTransfer.items is a getter, and it - and the items read from its
  // returned DataTransferItemList - cannot be assigned to. DataTransferItemLists
  // also cannot be constructed, so we have to use an array instead.

  Object.defineProperty(dataTransfer, 'items', {
    get() {
      return lodash__WEBPACK_IMPORTED_MODULE_1___default.a.map(oldItems, tryMockWebKit);
    }

  }); // When a real user drags file(s) over an element, dataTransfer.types always contains `['Files']`.
  // In Firefox however, the 'types' array is not properly populated when we construct our dataTransfer.

  if (files.length !== 0 && dataTransfer.types.length === 0) {
    Object.defineProperty(dataTransfer, 'types', {
      get() {
        // This is the value observed from real user events in Firefox 90.
        return ['application/x-moz-file', 'Files'];
      }

    });
  }

  return dataTransfer;
};'

Other

"playwright-webkit": "^1.28.0"

verdeimparat avatar Nov 25 '22 08:11 verdeimparat

@verdeimparat Thank you for providing a reproducible example! I am sorry you are having troubles getting this working. I took the example you provided and was able to successfully run it in open mode and run mode with Cypress 11.2.0 using [email protected]. Screen Shot 2022-12-23 at 2 30 28 PM Screen Shot 2022-12-23 at 2 35 22 PM

note: I was unable to launch the test running with playwright-webkit 1.29.0 or 1.29.1.

I also was unable to repo the error you logged when I removed the image.png from the fixtures to see if that triggered the error.

Are you still seeing this issue? Was there other configuration enabled and/or details that are important to reproduce this?

emilyrohrbough avatar Dec 23 '22 20:12 emilyrohrbough

Still not working on my side. Could be the OS fault? I see that u are using MAC OS.

verdeimparat avatar Jan 03 '23 09:01 verdeimparat

I should be able to try the reproduction out on windows either tomorrow or early next week

AtofStryker avatar Jan 18 '23 21:01 AtofStryker

Hi @verdeimparat. Sorry for the delay here, but I was able to reproduce your issue on Windows 10 Home with this reproduction repository.

AtofStryker avatar Jan 31 '23 18:01 AtofStryker

I have similar issue in docker container, However the upload works just fine on my local MacOS

ARG NODE_VERSION='18.13.0'
ARG CHROME_VERSION='110.0.5481.177-1'
ARG FIREFOX_VERSION='110.0.1'
ARG YARN_VERSION='1.22.19'


FROM cypress/factory

ENV TZ=Etc/UTC

RUN apt-get update && apt-get install cron -y

WORKDIR /app/tests/Cypress

Inside docker container I run

yarn ci
yarn playwright install-deps webkit
yarn playwright install
yarn cypress cache path
yarn cypress cache list

"playwright-webkit": "1.35.1", "cypress": "12.5.0",

I am getting the error from back end

["Must be a file of type: jpg, png, jpeg, rtf, doc, docx, xls, xlsx, pdf, txt, gif, bmp, tif, tiff, csv, zip.","Must be at least 1 kilobytes."]}

however, it is the jpg and it works in chrome and firefox in docker

I believe it is what it's sending

"------WebKitFormBoundaryNSyMpXAYQMMwB2ea\r\nContent-Disposition: form-data; name=\"file\"; filename=\"photo.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundaryNSyMpXAYQMMwB2ea--\r\n"

romankhomitskyi avatar Jul 11 '23 10:07 romankhomitskyi