I am getting started with using Selenium to test a React application that I have built.
In most simple JavaScript applications it is trivial to wire up a test where one uses the WebDriverWait class to wait for some event to signal that the test can proceed to the next step.
For example:
using (IWebDriver driver = new ChromeDriver())
{
driver.Navigate().GoToUrl($"{Properties.Settings.Default.ApplicationUrl}/Dashboard");
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => d.Title.StartsWith("dashboard", StringComparison.OrdinalIgnoreCase));
//Can do next thing....
Assert.IsTrue(true);
}
However things get a bit more complicated if we want to test a React application. Given that each component in your React application will each individually invoke their own lifecycle events, in their own time, it is extremely difficult to know when a given control has completed its Render() lifecycle.
I have played with a simple solution like:
//Add something like this to each React component
componentDidMount() {
if (!window.document.hasMyComponentMounted)
window.document.hasMyComponentMounted = true;
}
and then I can do something like this in my tests:
using (IWebDriver driver = new ChromeDriver())
{
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
driver.Navigate().GoToUrl($"{Properties.Settings.Default.ApplicationUrl}/Dashboard");
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => js.ExecuteScript("return window.document.hasHomeMounted"));
//Can do next thing....
Assert.IsTrue(true);
}
but this seems like a kinda sucky solution.
Has anyone encountered the same problem or know of potential workarounds (except for just using Thread.Sleep())?