I am wondering how do I disable javascript when using selenium so I can test server side validation.
I found this article but I don\'t know what to really do. Like I
Sometimes, profile.set_preference("javascript.enabled", False) does not work in Firefox. Use the below python to get around this:
from pyvirtualdisplay import Display
from selenium import webdriver
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
profile = webdriver.FirefoxProfile()
profile.update_preferences() #May or may not be needed
display = Display(visible=0, size=(1200, 800))
display.start()
browser = webdriver.Firefox(profile)
browser.get("about:config")
actions = ActionChains(browser)
actions.send_keys(Keys.RETURN)
actions.send_keys("javascript.enabled")
actions.perform()
actions.send_keys(Keys.TAB)
actions.send_keys(Keys.RETURN)
actions.send_keys(Keys.F5)
actions.perform()
browser.quit()
display.stop()
You don't need to disable JavaScript. If you fill out your form you can use JavaScript to submit your form e.g. use runScript
and window.document.forms[0].submit()
.
Whenever you call submit()
directly on a form, the form is submitted directly to the server, there is no onsubmit event fired, and therefore, no client-side validation. (Unless your form action is something like javascript:validateForm()
, in which case your system doesn't work when JavaScript is disabled).
I was trying to achieve the same in Chrome (in 2020), spent too much time on this, the final solution was to automate the disabling of Javascript in Chrome settings page.
To do that, i was writing a function to get Shadow DOM elements from Chrome with Javascript by the provided path, until i reached the level where the control i had to click on was located.
This is the function i was using for that (i found the solution here and modified a bit):
public IWebElement GetElementFromShadow(string[] Path)
{
IWebElement root = null;
foreach (string act in Path)
{
if (root == null)
{
root = (IWebElement)((IJavaScriptExecutor)_driver).ExecuteScript("return document.querySelector(arguments[0]).shadowRoot", act);
}
else
{
root = (IWebElement)((IJavaScriptExecutor)_driver).ExecuteScript("return arguments[0].querySelector(arguments[1]).shadowRoot", root, act);
}
}
return root;
}
Then in the test definition, i created an array of strings with the shadow dom path i found in DevTools, used the function above to get the WebElement from inside the nested shadowRoot, so i could click on it with Selenium:
string[] DisableJSShadowRootPath = { "settings-ui", "settings-main", "settings-basic-page", "settings-privacy-page", "category-default-setting", "settings-toggle-button", "cr-toggle" };
IWebElement control = _JSsettings.GetElementFromShadow(DisableJSShadowRootPath);
control.FindElements(By.TagName("span")).Where(e => e.GetAttribute("id") == "knob").First().Click();
The path can be easily found at the bottom ribbon of Chrome DevTools:
Set the browser name in the selenium settings to htmlunit
.
This is a driver that has JavaScript disabled by default https://code.google.com/p/selenium/wiki/HtmlUnitDriver . The JavaScript required for selenium to interact with the page will still be able to run.