Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Compatibility with shadow dom #74

Closed
stefanbrato opened this issue May 21, 2019 · 16 comments · Fixed by #79
Closed

[Feature] Compatibility with shadow dom #74

stefanbrato opened this issue May 21, 2019 · 16 comments · Fixed by #79
Assignees
Labels
enhancement New feature or request

Comments

@stefanbrato
Copy link

Current behavior:

Can this plug-in work with shadow dom as well ?
When I tried to use it with our application I got an exception the element is detached from dom.
It would be really nice if this plug-in can work with shadow-dom.

Desired behavior:

This plug-in works with shadow-dom. If it is working with shadow-dom if an example could be added to the read-me page would be really helpful.

Versions

@stefanbrato stefanbrato added the enhancement New feature or request label May 21, 2019
@abramenal
Copy link
Owner

Hi @stefanbrato
Thanks for the feedback!

Well, that's actually a nice one.
Can you please share any small snippet of your component implementation + tests as well as exception you get in order to get more context?
I think it might be quite easy one, but need to figure out what is not yet supported (hopefully not the event triggering).

@stefanbrato
Copy link
Author

stefanbrato commented May 21, 2019

Hello @abramenal ,

Here is a small snippet of the command added in support/commands.js:

Cypress.Commands.add("uploadFile", (fileName) => {
    cy.fixture(fileName).then(fileContent => {
        cy.get("other-app")
            .shadowGet("other-app-adp")
            .shadowGet("other-app-adp-file-add-modal")
            .shadowGet("div.drop-zone")
            .upload(
                    { fileContent, fileName, mimeType: 'application/json' },
                    { subjectType: 'drag-n-drop'},
                );
      });
});

Here is an example of the simple test we had for this upload feature:

it.only("should add a new file", () => {
            cy.uploadFile("example.json");
        })

And here is the exception we receive:

Error:       CypressError: cy.upload() failed because this element is detached from the DOM.

<div class="drop-zone">...</div>

Cypress requires elements be attached in the DOM to interact with them.

The previous command that ran was:

  > cy.shadowGet()

This DOM element likely became detached somewhere between the previous and current command.

Common situations why this happens:
  - Your JS framework re-rendered asynchronously
  - Your app code reacted to an event firing and removed the element

You typically need to re-query for the element or add 'guards' which delay Cypress from running new commands.

https://on.cypress.io/element-has-detached-from-dom

Regarding the snippet of the component code, we are working for a internal project closed source. We are working on a poc for this component and we will send it to you.

Please let me know if I can help you with more information.

@abramenal
Copy link
Owner

abramenal commented May 24, 2019

@stefanbrato I see the case now.
You're using functionality extension for shadow DOM support (that is not yet supported originally).
I see we need to introduce a new command like shadowUpload that will work on top of this package.

Prior to that I've created another package – https://github.com/abramenal/cypress-shadow-dom.
Hopefully will finish the implementation really soon – feel free to contribute 😈

After that, on top of shadow DOM package will make shadowUpload command inside cypress-file-upload thing.

Feel this coming in a week or so.. will let u know.

@abramenal
Copy link
Owner

@stefanbrato realized that's not a quite easy one to do 😈
Feel free to join testing & designing that package properly:
https://github.com/abramenal/cypress-shadow-dom

@stefanbrato
Copy link
Author

Hello @abramenal , indeed it seems it is a bit out of my league to do this modification, but we did find a workaround and I though it would be nice to share it, until the plugin is updated:

uploadFile(filename, fixturePath = 'swaggers/'){
        const button = this.uploadFileInput();
        const fixture = fixturePath + filename; 
        const type = 'application/json';

        button.then(subject =>
            cy.window().then(win =>
                cy.fixture(fixture, 'base64')
                .then((json) => {
                const el = subject[0];
                const blob = new Blob([JSON.stringify(json, null, 2)], {type : 'application/json'});
                const testFile = new win.File([blob], filename, { type });
                const dataTransfer = new win.DataTransfer();
                dataTransfer.items.add(testFile);
                el.files = dataTransfer.files;
                el.dispatchEvent(new CustomEvent('change'));
            })));
    }

@abramenal
Copy link
Owner

@stefanbrato that's a great finding!
It seems there's no need to spend effort on supporting shadow DOM but rather adjust the configuration inside to let cypress omit elements validation.
I will check that later today, anyways let you know if I found a way to.

@abramenal
Copy link
Owner

Implementation is done, need some time for proper testing – release for this improvement is coming.

@abramenal
Copy link
Owner

@stefanbrato

so now you can use the command for shadow dom components as well:

const fileName = 'data.json';

cy.fixture(fileName).then(fileContent => {
  yourWrappedShadowSubject.upload(
    { fileContent, fileName, mimeType: 'application/json' },
    { subjectNature: 'shadow', subjectType: 'drag-n-drop' },
  );
});

If you're using https://github.com/abramenal/cypress-shadow-dom
it's likely will look like:

const fileName = 'data.json';

cy.fixture(fileName).then(fileContent => {
  cy.document()
  .shadowGet('my-shadowed-form my-shadowed-dropzone')
  .upload(
    { fileContent, fileName, mimeType: 'application/json' },
    { subjectNature: 'shadow', subjectType: 'drag-n-drop' },
  );
});

@abramenal
Copy link
Owner

I am also working on reference solutions (aka recipes) to demonstrate what we can do with the plugin: #80

@abramenal
Copy link
Owner

abramenal commented Jun 28, 2019

@stefanbrato
Much thanks to you!
That was a great code snippet which helped to understand how to tweak the plugin.
I've added you to our honored contributors list 😈 😈 😈

@abramenal
Copy link
Owner

abramenal commented Jul 19, 2019

I've added a separate recipe to demonstrate this specific case:
https://github.com/abramenal/cypress-file-upload/tree/master/recipes/shadow-dom-native

@RuslanOmurbekov
Copy link

I am also working on reference solutions (aka recipes) to demonstrate what we can do with the plugin: #80

@stefanbrato

so now you can use the command for shadow dom components as well:

const fileName = 'data.json';

cy.fixture(fileName).then(fileContent => {
  yourWrappedShadowSubject.upload(
    { fileContent, fileName, mimeType: 'application/json' },
    { subjectNature: 'shadow', subjectType: 'drag-n-drop' },
  );
});

If you're using https://github.com/abramenal/cypress-shadow-dom
it's likely will look like:

const fileName = 'data.json';

cy.fixture(fileName).then(fileContent => {
  cy.document()
  .shadowGet('my-shadowed-form my-shadowed-dropzone')
  .upload(
    { fileContent, fileName, mimeType: 'application/json' },
    { subjectNature: 'shadow', subjectType: 'drag-n-drop' },
  );
});

Hello everyone,
I am facing the same issue and trying to use the code above. However i am getting an error on upload , Property 'upload' does not exist on type 'Chainable<Document, any>'. Do you have any suggestions on what i have to change ?
Thanks

@abramenal
Copy link
Owner

Hi @RuslanOmurbekov
Which version are you using for both packages?

@RuslanOmurbekov
Copy link

Hi @RuslanOmurbekov
Which version are you using for both packages?

Hi @abramenal I guess i am using the latest versions.
"cypress-file-upload": "^4.0.7"
"cypress-shadow-dom": "^1.4.0"

Should i downgrade versions?

@abramenal
Copy link
Owner

@RuslanOmurbekov nope, the thing is code snippet I gave is actual for cypress-file-upload v3.
If you're using v4, the proper command name is attachFile as it is stated in API docs.

@RuslanOmurbekov
Copy link

@RuslanOmurbekov nope, the thing is code snippet I gave is actual for cypress-file-upload v3.
If you're using v4, the proper command name is attachFile as it is stated in API docs.

Yes, i am using v4 and i was using 'attachFile'. Actually i figured out , the format of the file wasn't correct.
Anyways, @abramenal thanks a lot for help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants