I have a link which I can validate correctly which is followed by the code target="_blank". I do not wish to click the link as it takes me outside of the system I am testing and requires a new login. What I want to do is simply validate target="_blank" is shown after the link. I am working in Selenium webdriver and C#
// Try and find the link for eTMAs http://www.open.ac.uk/assessment/documents/New-eTMA-Interface_000.pdf
string eTMAslink = "http://www.open.ac.uk/assessment/documents/New-eTMA-Interface_000.pdf";
Console.WriteLine($"Checking for eTMAs link http://www.open.ac.uk/assessment/documents/New-eTMA-Interface_000.pdf");
IWebElement eTMAsLink = Globals.GetElementByhref(eTMAslink);
Assert.IsNotNull(eTMAsLink);
Console.WriteLine($"Found eTMAsLink link ", eTMAsLink);
// Now validate target="_blank"> how?
IWebElementdefines the GetAttribute method that you can use to check whether the attribute target is present on the link, e.g.:
Assert.IsNotNull(eTMAsLink);
var targetValue = eTMAslink.GetAttribute("target");
Assert.AreEqual("_blank", targetValue);
Here is how you handle exception. You may try to improve your code for asserting about:blank
using OpenQA.Selenium;
using NUnit.Framework;
public void checknewTab(IWebDriver driver)
{
try
{
/* New tab window with IJavaScriptExecutor */
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("window.open();");
/* Switch driver to last tab [which is blank tab] */
driver.SwitchTo().Window(driver.WindowHandles.Last());
/* Verify new Tab by using Assert If it is was not about:blank -
It will throw AssertionException */
Assert.AreEqual("about:blank", driver.Url);
}
catch(AssertionException ex)
{
/* Print [Console.Writeline] that there is not a new Tab
[about:blank] */
}
catch(Exception ex)
{
// Print to see other Exception
}
}
Related
PREFACE: After a lengthy Stack Overflow search I found two suggested solutions to solve the "element not interactable" problem I am having when I try to interact with the target node element. Neither of them worked, as described below.
I have a C# app that uses the OpenQA.Selenium package to remote control a YouTube web page. I am trying to click on a button on the page that opens a dialog box, but when I do I get the notorious "element not interactable" message. I found the following two suggestions on Stack Overflow:
Actions actions = new Actions(chromeDriver);
actions.MoveToElement(webElem);
actions.Perform();
And this suggestion that one commenter said is ill-advised because it can click on elements that are not visible or are below modal objects:
IJavaScriptExecutor executor = (IJavaScriptExecutor)chromeDriver;
executor.ExecuteScript("arguments[0].click();", webElem);
I tried the second one anyways to see if it worked. Unfortunately, with the first suggestion that uses the Actions interface, I still got "element not interactable" message but this time on the Perform() statement. The third attempt did not get the error message but it failed to click the button. I know this because clicking the button opens a dialog window when it works, and no dialog window appeared when I tried the third solution.
Below is the code I am using to try and click on the element. The collection it iterates are the elements I select via an XPath statement that finds the button I am want to click. It tries every button that matches the XPath statement and skips those that fail to work. Unfortunately, none of the 3 buttons found by the XPath statement work.
What is strange is that if I take the exact same XPath statement I am using in my C# app and plug it into the Chrome DevTools debugger, referencing the first element in the array of found elements, it works:
$x(strXPath)[0].click()
But so far nothing I have tried from C# app works. Does anyone have an idea on why I am having this problem?
public IWebElement ClickFirstInteractable(ChromeDriver chromeDriver)
{
string errPrefix = "(ClickFirstInteractable) ";
if (this.DOM_WebElemensFound == null || this.DOM_WebElemensFound.Count() < 1)
throw new NullReferenceException(errPrefix + "The DOM_WebElementsFound collection is empty.");
IWebElement webElemClicked = null;
foreach (IWebElement webElem in this.DOM_WebElemensFound)
{
// Try and "click" it.
try
{
// First make sure the element is visible, or we will get
// the "element not interactable" error.
/* FIRST ATTEMPT, didn't work.
*
webElem.scrollIntoView(true);
webElem.Click(); // <<<<<----- Error occurs here
*/
/* SECOND ATTEMPT using Actions, didn't work
* and I go the error message when the Perform() statement executes.
Actions actions = new Actions(chromeDriver);
actions.MoveToElement(webElem);
actions.Perform(); // <<<<<----- Error occurs here
*/
/* THIRD ATTEMPT using script execution, didn't work.
* I did not get the error message, but the button did not get clicked.
*/
IJavaScriptExecutor executor = (IJavaScriptExecutor)chromeDriver;
executor.ExecuteScript("arguments[0].scrollIntoView();", webElem);
executor.ExecuteScript("arguments[0].click();", webElem);
// Click operation accepted. Stop iteration.
webElemClicked = webElem;
break;
}
catch (ElementNotInteractableException exc)
{
// Swallow this exception and go on to the next element found by the XPath expression.
System.Console.WriteLine(exc.Message);
}
}
return webElemClicked;
}
I tried to reproduce your scenario by clicking on a "hidden" button, waiting for the modal to appear, then acting on that modal, etc.
I hope it helps you!
const string Target = #"https://www.youtube.com/";
using var driver = new ChromeDriver();
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20))
{
PollingInterval = TimeSpan.FromMilliseconds(250),
};
driver.Navigate().GoToUrl(Target);
// i don't consent cookies to
// save time, so just do it
// here manually and then press enter to console
Console.ReadLine();
var menuLocator = By.XPath("//a[#id = 'video-title-link'][1]" +
"/ancestor::div[#id = 'meta']" +
"/following-sibling::div[#id = 'menu']" +
"//button[#class = 'style-scope yt-icon-button']");
var menu = wait.Until(d => d.FindElement(menuLocator));
var actions = new Actions(driver);
actions.MoveToElement(menu).Click().Perform();
var shareLocator = By.XPath("//div[#id = 'contentWrapper']//*[normalize-space(text()) = 'Share']");
var share = wait.Until(d => d.FindElement(shareLocator));
actions.MoveToElement(share).Click().Perform();
var copyLinkLocator = By.XPath("//button[#aria-label = 'Copy']");
var copyLink = wait.Until(d => d.FindElement(copyLinkLocator));
actions.MoveToElement(copyLink).Click().Perform();
Here's the code.
browser = new FirefoxDriver();
browser.Navigate().GoToUrl("https://www.vicroads.vic.gov.au/registration/buy-sell-or-transfer-a-vehicle/buy-a-vehicle/check-vehicle-registration/vehicle-registration-enquiry");
Thread.Sleep(5000);
browser.FindElement(By.Name("ph_pagebody_0$phthreecolumnmaincontent_1$panel$VehicleSearch$RegistrationNumberCar$RegistrationNumber_CtrlHolderDivShown")).SendKeys("asdf");
It works ok but if I run in thread it shows element not visible.... why it's throwing in a thread?
Element could be non-visible cuz page didnt reload at check moment or website using dynamic names, classes etc.
You can try something like this:
IWebDriver browser = new FirefoxDriver();
browser.Navigate().GoToUrl("https://www.vicroads.vic.gov.au/registration/buy-sell-or-transfer-a-vehicle/buy-a-vehicle/check-vehicle-registration/vehicle-registration-enquiry");
while ( true ) {
try {
browser.FindElement(By.Name("ph_pagebody_0$phthreecolumnmaincontent_1$panel$VehicleSearch$RegistrationNumberCar$RegistrationNumber_CtrlHolderDivShown")).SendKeys("asdf");
break;
}
catch { Thread.Sleep(1000);}
}
Going by the xpath you tried out, it seems the name attribute is dynamic. To locate the text box for Registration number You can try either of the following options :
CssSelector :
browser.FindElement(By.CssSelector("input[class=text text xlong v_registrationNumber v_required][id^=ph_pagebody_)]")).SendKeys("asdf");
XPath :
browser.FindElement(By.XPath("//input[#class='text text xlong v_registrationNumber v_required'][starts-with(#id, 'ph_pagebody_')]")).SendKeys("asdf");
namespace ABC.ABCManager.UIAutomation.Authorization
{
[TestClass]
public class VerifyCreateUsersSendInvite : BaseTest
{
[TestMethod]
public void VerifySendAnInviteLink()
{
Actions actions = new Actions(driver);
selectAndClickOnCustomerName();
Thread.Sleep(3000);
try
{
//Click Send an Invite link
var LinksOnOverview = driver.FindElements(By.CssSelector(".popupFrameLink.summary-tool-link"));
LinksOnOverview[2].Click();
//Verification point to see "Send an Invite" link has opened by checking "TextName" textbox is present or not by using CSS selector
if (IsElementPresent(By.CssSelector("#FirstName")))
{
ExtentManager.verifySafely(driver.FindElement(By.CssSelector("#FirstName")).TagName, "input", "VerifySendAnInviteLink", "link has opened ", driver);
Console.WriteLine("'Send an Invite' link has opened ");
}
}
catch (Exception ex)
{
driver.Close();
}
}
}
}
In above code,I am clicking link "Send an Invitation" and after that, I am getting exception "Element not found" on the line :
if (IsElementPresent(By.CssSelector("#FirstName")))
.... I am inspecting element by CssSelector. I tried xpath then also same exception I am getting. I am unable to find any other element(including first name) on that pop up.Please suggest me solution. Thanks in advance!!!
Probably you should change frame on which you looking for elements
ReadOnlyCollection<string> windowHandles = driver.WindowHandles;
driver.SwitchTo().Window(windowHandles[1]);
// ELEMENTS on Second frame (window)
driver.SwitchTo().Window(windowHandles[0]);
// ELEMENTS on First Frame
try
{
List<IWebElement> frames = new List<IWebElement>(driver.FindElements(By.TagName("iframe")));
driver.SwitchTo().Frame(1);
//Verification point to see "Send an Invite" link has opened by checking Text Name textbox is present or not by using CSS selector
if (IsElementPresent(By.CssSelector("#FirstName")))
{
ExtentManager.verifySafely(driver.FindElement(By.CssSelector("#FirstName")).TagName, "input", "VerifySendAnInviteLink", "link has opened ", driver);
Console.WriteLine("'Send an Invite' link has opened ");
}
I want to test if there are no broken links on the website by getting all the links in list, clicking them and getting response if they are working. Can you suggest me a way to do it in c#?
namespace billingtest
{
[TestClass]
public class test
{
FirefoxDriver driver;
[TestInitialize()]
public void SyncDriver()
{
driver = new FirefoxDriver();
driver.Manage().Window.Maximize();
}
[TestMethod]
public void testwithadmin()
{
driver.Navigate().GoToUrl("http://localhost:52982");
driver.FindElement(By.Id("UserNameOrEmail")).SendKeys("aa");
driver.FindElement(By.Id("Password")).SendKeys("aa");
driver.FindElement(By.XPath(".//*[#id='main']/form/div[3]/input")).Click();
driver.FindElement(By.XPath(".//*[#id='content-main']/div/div/a[3]")).Click();
//Get all links, click them one by one and get response if they are working
}
[TestCleanup]
public void TearDown()
{
driver.Quit();
}
}
}
Check it using getTitle();
if it return something then go ahead
and if return false (means blank) then print that link.
There are a few things you could do depending on what you are looking for as a PASS. You could start by getting all the links on the page and iterating through the collection. That code is below. If you want to stay in the browser, you could click on each link and open it in a new browser window and verify the page. If you don't care about staying in the browser, you could get the href from each link and use this answer to validate the URLs.
ReadOnlyCollection<IWebElement> links = driver.FindElements(By.TagName("a"));
foreach (IWebElement link in links)
{
String href = link.GetAttribute("href");
// do something with href
}
I'm not the first time here with questions like this.
I have a Volvo auto parts catalog that is implemented as a client application to a local database and works only in IE8/9. I need to find and get some positions displayed in IE.
Here's an example of IE output:
It's just a table and nothing more.
And here's what I see in IE9 debug tools:
IE shows me full layout of a page where I can see a target table and rows with the data I need to get.
I wrote a simple class that should walk through all IE tabs and get HTML from the target page:
using System.Globalization;
using System.Text.RegularExpressions;
using SHDocVw;
namespace WebpageHtmlMiner
{
static class HtmlMiner
{
public static string GetWebpageHtml(string uriPattern)
{
var uriRegexPattern = uriPattern;
var regex = new Regex(uriRegexPattern);
var shellWindows = new ShellWindows();
InternetExplorer internetExplorer = null;
foreach (InternetExplorer ie in shellWindows)
{
Match match = regex.Match(ie.LocationURL);
if (!string.IsNullOrEmpty(match.Value))
{
internetExplorer = ie;
break;
}
}
if (internetExplorer == null)
{
return "Target page is not opened in IE";
}
var mshtmlDocument = (mshtml.IHTMLDocument2)internetExplorer.Document;
var webpageHtml = mshtmlDocument.body.parentElement.outerHTML.ToString(CultureInfo.InvariantCulture);
return webpageHtml; //profit
}
}
}
It seems to work fine but instead of what I see in IE debug tools I get HTML code with tons of javascript functions and no data in target table.
Is there any way to get exactly what I see in IE debug tools?
Thanks.
You can get the original source (the one sent by the server) in "Script" tab (this works both on my IE8 and my IE10).
If you do not use AJAX, I think you can right-click on the page and choose Display Souce option too.