Got problem with proper method for waiting until element is visible.
Let me describe how page works. Page is loaded, dropdown is shown, but then, there is progress bar appearing (jquery block UI), because data is loaded from db, according to some conditions.
So i used two methods, one for wait for element to be present, then wait to dissapear, but on some occassions (maybe there are loaded in other way, etc.) i got Internet Explorer crash (so no exception by selenium, but crash of IE). Below methods and execution:
public IWebElement WaitForPageElementToLoad(By by, IWebDriver driver, int timeInSeconds)
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeInSeconds));
wait.Until(ExpectedConditions.ElementIsVisible(by));
return driver.FindElement(by);
}
public void WaitForPageElementToBeRemoved(By by, IWebDriver driver, int timeInSeconds)
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeInSeconds));
wait.Until<bool>((d) =>
{
try
{
IWebElement element = d.FindElement(by);
return false;
}
catch (NoSuchElementException)
{
return true;
}
});
}
Execution:
WaitForPageElementToLoad(By.XPath("//div[#class='blockUI blockOverlay']"), ieDriver, 25);
WaitForPageElementToBeRemoved(By.XPath("//div[#class='blockUI blockOverlay']"), ieDriver, 25);
WaitForPageElementToLoad(By.Id("clientSelector"), ieDriver, 25);
I think webdriver is searching through elements during some work, i do not how to figure that out, to write it properly. Maybe you'll have some hints, etc.
Related
Angular Material Select (mat-select) inside Form Field (mat-form-field) ignores Selenium click
When test runs, dropdown doesn't appear after click is made by Selenium. If it is made manually by me, test continues and passes.
I also tried to use SelectElement class but it's not applicable since mat-select doesn't use any select elements
public class Page definition:
[FindsBy(How = How.XPath, Using = "//*[#id='form']//mat-form-field//*[#class='mat-form-field-flex' and .//*[#formcontrolname='network']]")] // also tried all surrounding elements from DOM including mat-form-field and mat-select (look at attached screenshot)
public IWebElement _formNetworkFormControl;
public bool IsFormNetworkFormControlComponentPresent()
{
return ExtendedWebElementOperations.IsElementDisplayed(_formNetworkFormControl);
}
// Click dropdown
public void ClickFormNetworkFormControl(IWebDriver webdriver)
{
// Wait is needed until data is loaded and select is enabled
WebDriverWait wait = new WebDriverWait(webdriver, timeout: TimeSpan.FromSeconds(15));
wait.Until(ExpectedConditions.ElementToBeClickable(_formNetworkFormControl));
_formNetworkFormControl.Click();
}
// To select option after dropdown click
public void SelectByOptionName(IWebDriver webdriver, string optionName)
{
string xpath = $"//mat-option[span[text()[contains(.,'{optionName}')]]]";
WebDriverWait wait = new WebDriverWait(webdriver, timeout: TimeSpan.FromSeconds(5));
wait.Until(ExpectedConditions.ElementIsVisible(By.XPath(xpath)));
IWebElement optionNameSelect = webdriver.FindElement(By.XPath(xpath));
optionNameSelect.Click();
}
Test:
var testedPage = new Page(Driver);
testedPage.ClickAddRingTestFormNetworkFormControl(Driver); // click is made but dropdown doesn't appear
testedPage.SelectByOptionName(Driver, networkName); // if select is clicked manually, this works great
The problem is that mat-select has aria-disabled='true' until required data is loaded, so
wait.Until(ExpectedConditions.ElementToBeClickable(_formNetworkFormControl));
doesn't cover this case.
I fixed it with updating Page class following way:
public IWebElement IsElementHasTrueAriaDisabledAttribute(IWebDriver webdriver, IWebElement element)
{
if (element.GetAttribute("aria-disabled").Equals("false"))
{
return element;
}
return null;
}
public void ClickFormNetworkFormControl(IWebDriver webdriver)
{
WebDriverWait wait = new WebDriverWait(webdriver, timeout: TimeSpan.FromSeconds(15));
wait.Until<IWebElement>((d) =>
{
return IsElementHasTrueAriaDisabledAttribute(d, _formNetworkFormControl);
});
_formNetworkFormControl.Click();
}
I try to send keys to input field but can't do it...
I have tried different ways to wait till element is visible but got timeout exceptions...
IWebElement userName = driver.FindElement(By.Id("UserName"));
IWebElement userPassword = driver.FindElement(By.Id("Password"));
IWebElement subButton = driver.FindElement(By.XPath(("//button[contains(.,'Вхід')]")));
while (true)
{
userName = driver.FindElement(By.Id("UserName"));
if (userName.Displayed)
{
userName.SendKeys("test");
break;
}
}
subButton.Click();
Using this method gives me always timeout:
public static void WaitForElementLoad(By by, int timeoutInSeconds)
{
if (timeoutInSeconds > 0)
{
WebDriverWait wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(timeoutInSeconds));
wait.Until(ExpectedConditions.ElementIsVisible(by));
}
}
If its hidden just send/execute a simple js by selenium that will show the element. But it cant be a little bit more tricki. Set the window size to a bigger one eg 2000x2000. If something is not placed in the viewport selenium will not see it.
please try to use JavaScript to scroll to the element and then perform other operations on the element
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
I am new to Selenium and C# and creating an automated test whereby I create something and delete it straightaway (all in the same test).
The last step in my test is to verify the name of the item I've deleted is no longer visible - this is where I seem to be getting stuck.
I am in a modal dialog and the item is visible in the background, so once I confirm the deletion in the modal dialog, the next step is to verify the item name is no longer visible, but the code does see the name and therefore throws an exception because it is true instead of my expected result of false.
See below the code I'm using:
public bool DeletedCategoryNoLongerVisible(string CategoryDisplayName) {
try {
WebDriverWait wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(20));
wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath("//*[#id='10_anchor']")));
Driver.FindElement(By.XPath($ "//*[#class='jstree-anchor'][text()='{CategoryDisplayName}']"));
return false;
} catch (Exception) {
return true;
}
}
You can wait for the targeted element to be missing or for its displayed text to be empty with InvisibilityOfElementWithText:
new WebDriverWait(Driver, TimeSpan.FromSeconds(20))
.Until(ExpectedConditions.InvisibilityOfElementWithText(By.XPath(...), CategoryDisplayName));
And if the element is hidden with another element on top of it, then try to click it until failure:
new WebDriverWait(Driver, TimeSpan.FromSeconds(20))
.Until((driver) => {
try {
driver.FindElement(By.XPath(...)).Click();
return false;
} catch (WebDriverException) {
return true;
}
});
I have a number of tests. Sometimes if an element can't be found it just clicks on the top left of the screen. This doesn't happen all the time however it does happen. I'm not sure why this is happening. In my setUp method I'm telling it to click the element "Maximize" however if it can't find that element I put it into a catch and ignore it. For some reason when it can't find the element it just clicks on the top left corner of the screen that has the application session.
Has anyone any ideas why this is happening or is it just how selenium sometimes responds
My code is as follows
private string wordId = OfficeVersion.Word();
private string excelId = OfficeVersion.Excel();
private string powerPointId = OfficeVersion.PowerPoint();
private const string AppDriverUrl = "http://127.0.0.1:4723";
public static WindowsDriver<WindowsElement> excelSession;
public static WebDriverWait webDriverWait;
xl.Workbook WB;
public static bool skipTearDown = false;
WindowsElement create;
WindowsElement blankWorkBook;
public static DesiredCapabilities appCapabilities = new DesiredCapabilities();
[TestInitialize]
appCapabilities.SetCapability("app", excelId);
var initialSession = new WindowsDriver<WindowsElement>(new Uri(AppDriverUrl), appCapabilities);
var capabilities = new DesiredCapabilities();
capabilities.SetCapability("app", "Root");
excelSession = new WindowsDriver<WindowsElement>(new Uri(AppDriverUrl), capabilities);
webDriverWait = new WebDriverWait(excelSession, TimeSpan.FromSeconds(10));
CommonMethods.keyCheck(excelSession);
webDriverWait = new WebDriverWait(excelSession, TimeSpan.FromSeconds(10));
CommonMethods.IsElementDisplayed(excelSession, new StackTrace(true).GetFrame(0).GetFileLineNumber(), new StackTrace(true).GetFrame(0).GetMethod(), "CreateErrorIcon", "Create error when launching Excel");
try
{
This is the element I'm having trouble ignoring if it doesn't exist
webDriverWait.Until(ExpectedConditions.ElementToBeClickable(excelSession.FindElementByName("Maximize"))).Click();
}
catch (Exception)
{
//ignore
}
You can try to get the current window handle first and then attempt to locate and get the Webelement that points to the Maximize button for the window. Possibly, you might also need give a simple wait on the WebElement locate just to be safe.
This api might be useful for a C# client to selenium - driver.SwitchTo().Window(handle)
And for details, you can check here
I was running into the same problem when trying to select an item from a combo-box. Trying click on the item would always just result in a click on the top left of the screen. Super frustrating.
I got around it by using an Action to move the mouse to the element and then performing a click.
var a = new Actions(Session);
a.MoveToElement(v);
a.Click();
a.Perform();
I work with webDriver in #IE9 and I find one problem. If I started tests in Run mode, then all test fail because webDriver not exists (two window ie), but if I put breakpoint in tests and start tests Debug mode I have passed all tests. Please tell me, what do, because I don't know.
This my code:
private void MyMethods(IWebdriver driver)
{
foreach (var item in driver.WindowHandles) // if I put breakpoint, I see 2 count Window Handles else this methods don't work.
{
if (driver.SwitchTo().Window(item).Title == "PortalSubMenuPopupForm")
{
driver.SwitchTo().Window(item);
break;
}
}
}
Selenium has an "issue" with IE where new windows might not appear on the WindowHandles list right away.
The solution is either
wait a fixed amount of time before calling driver.WindowHandles
or
use the WebDriverWait class to wait for the number of elements under WindowHandles to change
I think the second one is more robust. Here is a quick implementation:
public void LaunchNewWindow(IWebElement element)
{
int windowsBefore = driver.WindowHandles.Count;
element.Click();
TimeSpan timeout = new TimeSpan(0, 0, 10);
WebDriverWait wait = new WebDriverWait(driver, timeout);
wait.Until((_driver) =>
{
return _driver.WindowHandles.Count != windowsBefore;
//optionally use _driver.WindowHandles.Count > windowsBefore
});
}
Now you can use the function like so:
IWebElement clickMe = //some element that launches a new window
LaunchNewWindow(clickMe);
foreach (var item in driver.WindowHandles)
{
//etc.
}