英文:
Cypress and file upload using selectFile() with drag n drop option
问题
我正在尝试使用Cypress测试文件上传小部件的功能。
我尝试过的Cypress测试如下:
const filePath = './cypress/fixtures/example.jpg';
cy.get('.dropzone')
.selectFile(filePath,
{ action: 'drag-drop',
force: true, }).trigger('drop', {force: true})
以及
cy.get('.dropzone > input[type="file"]').should('exist').invoke('show')
.selectFile(filePath, {
action: 'drag-drop',
force: true,
log: true,
})
.trigger('drop', {force: true})
以及
cy.get('.dropzone')
.children('input[type="file"]')
.should('exist')
.invoke('show')
.selectFile(filePath, { force: true })
.then(input => {
expect(input[0].files[0].name).to.equal('example.jpg')
})
.wait(6000)
.trigger('dragstart', { force: true,
dataTransfer: dataTransfer })
.wait(50)
.trigger('dragover', { force: true })
.wait(50)
.trigger('drop', { force: true })
.wait(50)
.trigger('dragend', { force: true })
.wait(50)
.trigger('change', { force: true });
以及
cy.document().get('.dropzone')
.children('input[type="file"]').selectFile(filePath, { action: 'drag-drop' })
以及
cy.document().get('.dropzone')
.children('input[type="file"]')
.selectFile(filePath, { action: 'drag-drop', force: true })
.trigger('drop', { force: true });
执行测试的HTML如下:
<div tabindex="0" role="button" class="dropzone svelte-817dg2" style="">
<input accept="image/*" type="file" name="avatar" autocomplete="off" tabindex="-1" style="display: none;">
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
我正在使用此Svelte组件进行拖放文件上传 - https://github.com/thecodejack/svelte-file-dropzone
然而,在两种情况下以及所有变化的情况下,测试从未成功上传文件。
但是,在Cypress Chrome浏览器中,我能够手动成功执行拖放操作。
英文:
I'm attempting to test, using cypress, the functionality of a file upload widget.
The cypress tests which I've tried are:
const filePath = './cypress/fixtures/example.jpg'
cy.get('.dropzone')
.selectFile(filePath,
{ action: 'drag-drop',
force: true, }).trigger('drop', {force: true})
and
cy.get('.dropzone > input[type="file"]').should('exist').invoke('show')
.selectFile(filePath, {
action: 'drag-drop',
force: true,
log: true,
})
.trigger('drop', {force: true})
and
cy.get('.dropzone')
.children('input[type="file"]')
.should('exist')
.invoke('show')
.selectFile(filePath, { force: true })
.then(input => {
expect(input[0].files[0].name).to.equal('example.jpg')
})
.wait(6000)
.trigger('dragstart', { force: true,
dataTransfer: dataTransfer })
.wait(50)
.trigger('dragover', { force: true })
.wait(50)
.trigger('drop', { force: true })
.wait(50)
.trigger('dragend', { force: true })
.wait(50)
.trigger('change', { force: true });
and
cy.document().get('.dropzone')
.children('input[type="file"]').selectFile(filePath, { action: 'drag-drop' })
and
cy.document().get('.dropzone')
.children('input[type="file"]')
.selectFile(filePath, { action: 'drag-drop', force: true })
.trigger('drop', { force: true });
The html that the tests are executing against is:
<div tabindex="0" role="button" class="dropzone svelte-817dg2" style="">
<input accept="image/*" type="file" name="avatar" autocomplete="off" tabindex="-1" style="display: none;">
<p>Drag 'n' drop some files here, or click to select files</p>
</div>
I am using this svelte component for the drag 'n' drop file upload - https://github.com/thecodejack/svelte-file-dropzone
In both cases, and every variation on these, the tests never actually upload a file.
However, in the cypress chrome browser, I'm able to manually perform the drag n drop action successfully.
答案1
得分: 4
I checked out your code and couldn't get .selectFile()
to work. Just used the HTML segment you gave, ran it with VS Code live server (I know it's a svelte app, but..).
Using the simplest test, should at least be able to see the file attached to the internal <input>
.
Note {action:'drag-drop'}
searches for the <input>
within div.dropzone
.
const filePath = './cypress/fixtures/example.jpg';
cy.get('.dropzone')
.selectFile(filePath, {action:'drag-drop'})
cy.get('.dropzone')
.find('input')
.then($input => $input[0].files)
// assert some things about the input's FileList...
.should('have.length', 1)
.and(fileList => expect(fileList[0].name).to.eq('example.jpg'))
.and(fileList => expect(fileList[0].size).to.eq(159355))
But this fails, which makes me think there's a bug in .selectFile()
. The other weird thing is the assert
is green as if passing, but actually throws an AssertionError.
Update: Adding "input" to selector
It will work if you add input
to the .dropzone
selector, but you also need the {force: true}
option as the input is hidden.
const filePath = './cypress/fixtures/example.jpg';
cy.get('.dropzone input')
.selectFile(filePath, {force: true})
cy.get('.dropzone')
.find('input')
.then($input => $input[0].files)
// assert some things about the input's FileList...
.should('have length', 1)
.and(fileList => expect(fileList[0].name).to.contain('example.jpg'))
.and(fileList => expect(fileList[0].size).to.eq(159355))
If you swap in the older 3rd-party cypress-file-upload, it works.
// path applied is assumed to be /cypress/fixtures/
const filePathInFixtures = 'example.jpg'
cy.get('.dropzone')
.attachFile(filePathInFixtures, { subjectType: 'drag-n-drop' })
cy.get('.dropzone')
.find('input')
.then($input => $input[0].files)
// assert some things about the input's FileList...
.should('have length', 1)
.and(fileList => expect(fileList[0].name).to.eq('example.jpg'))
.and(fileList => expect(fileList[0].size).to.eq(159355))
That gets the file attached, but probably you need to trigger some event to kick off the actual upload. I can't tell what that would be from the info you gave, but try input
or change
to start with.
英文:
I checked out your code and couldn't get .selectFile()
to work. Just used the HTML segment you gave, ran it with VS Code live server (I know it's a svelte app, but..).
Using the simplest test, should at least be able to see the file attached to the internal <input>
.
Note {action:'drag-drop'}
searches for for the <input>
within div.dropzone
.
const filePath = './cypress/fixtures/example.jpg'
cy.get('.dropzone')
.selectFile(filePath, {action:'drag-drop'})
cy.get('.dropzone')
.find('input')
.then($input => $input[0].files)
// assert some things about the input's FileList...
.should('have.length', 1)
.and(fileList => expect(fileList[0].name).to.eq('example.jpg'))
.and(fileList => expect(fileList[0].size).to.eq(159355))
But this fails, which makes me think there's a bug in .selectFile()
. The other weird thing is the assert
is green as if passing, but actually throws an AssertionError.
Update: Adding "input" to selector
It will work if you add input
to the .dropzone
selector, but you also need the {force: true}
option as the input is hidden.
const filePath = './cypress/fixtures/example.jpg'
cy.get('.dropzone input')
.selectFile(filePath, {force: true})
cy.get('.dropzone')
.find('input')
.then($input => $input[0].files)
// assert some things about the input's FileList...
.should('have.length', 1)
.and(fileList => expect(fileList[0].name).to.contain('example.jpg'))
.and(fileList => expect(fileList[0].size).to.eq(159355))
If you swap in the older 3rd-party cypress-file-upload
, it works.
// path applied is assumed to be /cypress/fixtures/
const filePathInFixtures = 'example.jpg'
cy.get('.dropzone')
.attachFile(filePathInFixtures, { subjectType: 'drag-n-drop' })
cy.get('.dropzone')
.find('input')
.then($input => $input[0].files)
// assert some things about the input's FileList...
.should('have.length', 1)
.and(fileList => expect(fileList[0].name).to.eq('example.jpg'))
.and(fileList => expect(fileList[0].size).to.eq(159355))
That gets the file attached, but probably you need to trigger some event to kick off the actual upload. I can't tell what that would be from the info you gave, but try input
or change
to start with.
答案2
得分: 0
以下是翻译好的内容:
感谢@Fody提供了详细的示例。
然而,这些仍然没有起作用。
下面的方法有效,但不够稳定。在触发事件之前需要等待,并且我猜测不稳定性是因为等待时间不够长。
const filePathInFixtures = 'example.jpg'
cy.get('.dropzone')
.attachFile(filePathInFixtures, { subjectType: 'drag-n-drop' })
.wait(2000)
.trigger('change', { force: true })
cy.get('.dropzone')
.find('input', { timeout: 10000 })
// .wait(1000)
.trigger('change', { force: true })
.then($input => $input[0].files)
// 断言一些关于输入的 FileList 的内容...
.should('have.length', 1)
.and(fileList => expect(fileList[0].name).to.contain('example.jpg'))
.and(fileList => expect(fileList[0].size).to.eq(40319));
英文:
Many thanks goes to @Fody for providing detailed examples.
However, these still did not work.
The below works, but is flaky. There is a need to wait
before triggering the event. And I guess the flakiness is due to not waiting long enough.
const filePathInFixtures = 'example.jpg'
cy.get('.dropzone')
.attachFile(filePathInFixtures, { subjectType: 'drag-n-drop' })
.wait(2000)
.trigger('change', { force: true })
cy.get('.dropzone')
.find('input', { timeout: 10000 })
// .wait(1000)
.trigger('change', { force: true })
.then($input => $input[0].files)
// assert some things about the input's FileList...
.should('have.length', 1)
.and(fileList => expect(fileList[0].name).to.contain('example.jpg'))
.and(fileList => expect(fileList[0].size).to.eq(40319));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论