-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Ability to disable javascript for the url under test #1611
Comments
This is very possible, seems like all that needs to done is strip all the |
well, we can strip all JavaScript tags and inline handlers, but this does not make |
Could we not simply strip |
We could strip all JS but that would not force the browser iframe to show noscript elements
…Sent from my iPhone
On Apr 23, 2018, at 21:10, Ben Kucera ***@***.***> wrote:
Could we not simply strip <noscript> and </noscript> , but leave everything inside the tags there?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
+1 to this, (apologies for commenting but not contributing). I just wanted to say this would be really useful for sites which have to support browsers with javascript disabled. It often gets missed in automated tests. |
@maxcbc if you 👍 the top level comment, that will help us sort issues by community interest |
My use case is slightly different - I want to check how the page behaves before JS runs to see if it matches our SEO needs. Is there any known workaround to achieving that? |
Any update on this? my case is javascript will call html output to the page when i turn off javascript the html will load. |
I would really appreciate this feature for SEO purposes too. |
Likewise, I want it to test if my react server side rendering is working. For now I'm going to settle with making an http request and grepping the resulting text or something - but it's far from ideal. |
someone could try loading a no-script extension and match it to only run on the |
I'd love the ability to do this. I've recently attempted to migrate a project dependencies and 2 of them broke Next.js SSR support. A way for automating such tests would be great. Because I didn't automatically detect this SSR regression, I updated multiple other packages before understanding SSR was broken. Then, I had to replay the online preview of each manually, by disabling JS in the browser. At some point, I figured out that the issue was coming from next-with-apollo dependency (MAJOR version update) (see lfades/next-with-apollo#126) and tried to rollback this particular dep to its previous version, which, surprisingly, didn't work out because another dependency that I also had updated was causing the same regression (react-apollo (PATCH version update), see apollographql/react-apollo#3902) Eventually, I had to rewrite my git history to get back in time and replay all commits one by one until I figured this whole plot out. Which took me some 3-5h of investigation. All this to say that I'd love a way to automate this, and ensure some other PATCH dependency update doesn't break some feature again in the future. And, I got lucky here, because I had been meticulous and deployed an online version after each package update (gave me ability to test afterwards and find origin of regression). Otherwise it could (would) have taken me days to figure this out. |
So is this in theory possible to implement? If so where would I start for creating a PR? |
I've been using @bahmutov 's handy guide here: https://glebbahmutov.com/blog/ssr-e2e/ Issue is if I have two such tests, the second |
This guide is nice and helps a bit. It still does not reveal the |
I am trying cy.state("window").parent.document.querySelector(".iframes-container iframe").sandbox = ""; but it seems the iframe is already sandboxed but it does not show the |
Update: This seems to be almost done: describe("noscript", function () {
it("should not show the Get Codes button", function() {
cy.request("/")
.its("body")
.then(html => {
debugger
const parentDocument = cy.state("window").parent.document
const iframe = parentDocument.createElement("iframe")
const oldIframe = parentDocument.querySelector(".iframes-container iframe")
iframe.id = oldIframe.id
iframe.className = oldIframe.className
iframe.sandbox.add("allow-forms")
iframe.srcdoc = html
oldIframe.parentNode.replaceChild(iframe, oldIframe)
//cy.state("document").write(html)
})
cy.get('#encrypt').should('be.disabled')
})
}); It shows all the But the I guess that's because the Any ideas @bahmutov? |
One step more: With describe("noscript", function () {
it("should not show the Get Codes button", function() {
const parentDocument = cy.state("window").parent.document
const iframe = parentDocument.querySelector(".iframes-container iframe")
iframe.sandbox.add("allow-forms")
iframe.src = "http://htpc:4000/"
cy.get('#encrypt').should('be.disabled')
})
}); It was complaining about Cross-Site access, which does not make much sense since the iframe uses the same host like the spec. |
This could be neatly packaged into extending the Cypress.Commands.overwrite('visit', (orig, url, options = {}) => {
const parentDocument = cy.state("window").parent.document
const iframe = parentDocument.querySelector(".iframes-container iframe")
if (false === options.script) {
if (false !== Cypress.config("chromeWebSecurity")) {
throw new TypeError("When you disable script you also have to set 'chromeWebSecurity' in your config to 'false'")
}
iframe.sandbox = ""
} else {
// In case it was added by a visit before, the attribute has to be removed from the iframe
iframe.removeAttribute("sandbox")
}
return orig(url, options);
}) And the spec gets very clean then: describe("noscript", function () {
it("should not show the Get Codes button", function() {
cy.visit("/", { script: false })
cy.contains("The password is encrypted locally and for that you need to enable JavaScript.").should("exist")
cy.get('button')
.first()
.should('be.disabled')
.contains("Please enable JavaScript")
})
}); |
Any thoughts on my solution @bahmutov? |
@pke The workaround does appear to work. This workaround would only work in Chrome currently.
{
"chromeWebSecurity": false
}
Cypress.Commands.overwrite('visit', (orig, url, options = {}) => {
const parentDocument = cy.state("window").parent.document
const iframe = parentDocument.querySelector(".iframes-container iframe")
if (false === options.script) {
if (false !== Cypress.config("chromeWebSecurity")) {
throw new TypeError("When you disable script you also have to set 'chromeWebSecurity' in your config to 'false'")
}
iframe.sandbox = ""
} else {
// In case it was added by a visit before, the attribute has to be removed from the iframe
iframe.removeAttribute("sandbox")
}
return orig(url, options);
})
it('test', () => {
cy.visit('index.html', { script: false })
cy.get('h1').contains('JavaScript is disabled')
})
<html>
<body>
Hello, world
<noscript>
<h1>JavaScript is disabled</h1>
</noscript>
</body>
</html> |
Hi, I still have trouble with this issue, when running multiple tests that needs JS to be disabled. Cypress.Commands.add("visitAsHtml", (route: string) => {
cy.request(route)
.its("body")
.then((html) => {
// remove the application code JS bundle
html = html.replace(
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
""
);
cy.document().invoke({ log: false }, "write", html);
});
// now we can use "normal" Cypress api on the page
}); The problem is that if you do this: cy.visitAsHtml("/fr/foobar")
cy.get("html")
.should("have.attr", "lang", "fr")
cy.visitAsHtml("/en/foobar")
cy.get("html")
.should("have.attr", "lang", "en") The second assertion will fail, you still have the page in French while you should not. This is a false positive, the HTML response is correct, but Even if you create 2 tests, it still doesn't work. |
|
This is an important feature to do e2e test of things Angular Universal. |
Hi @eric-burel , I know it's been a while since you added your comment, (I'm new to cypress), I found your solution quite useful! To fix your problem with the visitAsHtml command, you need to have into account that Cypress.Commands.add("visitAsHtml", (route: string) => {
cy.request(route)
.its("body")
.then((html) => {
// remove the application code JS bundle
html = html.replace(
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
""
);
cy.document().invoke({ log: false }, "open"); // <-- Add This
cy.document().invoke({ log: false }, "write", html);
cy.document().invoke({ log: false }, "close"); // <-- And this
});
}); The above code allows to override the entire document, instead of appending if it already existed within the same test. Hope this helps you and anyone looking at this thread. |
Hi @JeyDotC , check out our community chat, it can be helpful for debugging or answering questions on how to use Cypress. |
I would like to be able to use Cypress to test an application when Javascript is disabled.
Current behavior:
Cypress makes itself appear to run from the same domain as the application under test and Chrome allows Javascript to be disable by domain only, so Javascript cannot be disabled without affecting Cypress itself.
Desired behavior:
The ability to disable javascript for the url under test, possibly with:
The text was updated successfully, but these errors were encountered: