Selenium - iframe within iframe - c#

I am trying to find iframe within iframe using Selenium WebDriver. I have a scenario where a popup opens in a website which itself is an iframe and this in turn contains 4 richedit textboxes which are nothing but iframes. Here is how i am trying to do it. If i check the foreach loop, i get 4 iframes correctly which suggests that i am reaching right elements. What can be the reason for failure for not able to get correct tags inside iframe? Here is my code.
ReadOnlyCollection<IWebElement> topItem = driver.FindElements(By.XPath("//iframe[#src='Edit.aspx']"));
Utility.Instance.WaitUntilFrameLoaded(topItem[0]);
Thread.Sleep(2000);
ReadOnlyCollection<IWebElement> elements = Utility.Instance.WaitUnitElementsAppearsByXPath("//div[#id='ctlPanel']//table/tbody/tr[2]//iframe[#src='javascript:true;']");
Thread.Sleep(1000);
foreach(IWebElement eleFrame in elements)
{
Utility.Instance.WaitUntilFrameLoaded(eleFrame);
IWebElement body = driver.FindElement(By.TagName("body"));
body.Click();
driver.SwitchTo().DefaultContent();
Utility.Instance.WaitUntilFrameLoaded(topItem[0]);
}
However i always get the message that the element with tag name body not found. If i debug, i see html which contains a body tag. I am not sure why it does not provide me back with the element.

Related

Unable to locate an element implemented as <td> using Selenium Web Driver

I wanted to locate the value of BNK1 using Selenium web driver by C#. my local website i found have 2 iframe. i have try to change to get my iframe to change to detail frame for me to get my value of BNK1 in the table.
I had no idea what going on with the problem that i not able locate the iframe by using XPath.
but i having error "no such element: Unable to locate element: {"method":"xpath","selector":"//iframe[#class='tabcontentiframe']"}
IWebElement detailFrame = driver.FindElement(By.XPath("//iframe[#class='tabcontentiframe']"));
driver.SwitchTo().Frame(detailFrame);
IWebElement element = driver.FindElement(By.XPath("//table/tbody/tr/td[contains(text(),'BNK1')]"));
String text = element.Text;
First, let's get sure that your page is fully loaded before trying anything, using a heavy-hand approach,
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
Second, assuming the element you want to access is inside an iframe, you first need to switch to it. Actually, you mention in comment that you have two nested iframes,
// Let's switch to the parent frame
IWebElement tabcontentiframe = driver.FindElement(By.XPath("//iframe[#class='tabcontentiframe']"));
driver.SwitchTo().Frame(tabcontentiframe);
// Let's switch to the child frame
IWebElement iframeHome = driver.FindElement(By.XPath("//iframe[#id='iframeHome']"));
driver.SwitchTo().Frame(iframeHome);
Now, you can do
IWebElement element = driver.FindElement(By.XPath("//table/tbody/tr/td[contains(text(),'BNK1')]"));
// or By.XPath("//td[contains(text(),'BNK1')]")
// or By.XPath("//td[text()='BNK1']")
When you are done, you may want to switch back to the main frame,
driver.SwitchTo().DefaultContent();
You can find the element by using the relative xpath:
IWebElement element = driver.FindElement(By.XPath("//td[text()='BNK1']"));

Selenium how to click on placeholde inside div

hi. I want to click on this placeholder inside div, how can I do it, I tried Xpath but it doesnt work.
It seems your input field is inside an iframe. You have to switch to iframe first and then try to sendkeys.
IWebElement iframeElement= driver.FindElement(By.Name("top"));
driver.SwitchTo().Frame(iframeElement);
IWebElement element = driver.FindElement(By.Id("username"));
element.SendKeys("text");
Note: As in question there is no detail about iframe iframeElement so I took this name from input element. You can change locator if it is not correct

selenium - trying to populate 1st iframe on page but finds 2nd

I am trying to populate first iframe on my page. It has 2 iframes on it. I am using the following code but it keeps populating the 2nd iframe for reasons unknown to me.
List<IWebElement> iframeList = Client.WebDriver.FindElementsByXPath(".//iframe");
IWebDriver overDrive = Client.WebDriver.Driver.SwitchTo().Frame(iframeList[0]);
IWebElement bodyLogin = overDrive.FindElement(By.TagName(("body")));
bodyLogin.SendKeys("My Text Message");

C# selenium webdriver css selector for label with only text Sign Out

I was not able to get satisfactory answer after searching on google.
So could you please guide me on this?
I have a div containing li,a,labels below it.
I am able to find the div using CssSelector by its class name.
Now inside this div I want to get a label with its text and then click on it.
The label is as belo:
<label>Sign Out</label>
How to do that ?
I have a working solution using XPath and iterating over all labels inside div, but I am unable to get it using CssSelector.
My Solution:
IWebElement menu = CurrentDriver.FindElement(By.CssSelector("div[class='menu-panel right']"));
IWebElement logoutLabel = menu.FindElement(By.XPath("//label[text()='Sign Out']"));
or
by using foreach:
var coll = menu.FindElements(By.TagName("label"));
foreach (var label in coll)
{
if(label.Text.Trim() =="Sign Out")
{
Log("Sign out was found.");
label.Click();
break;
}
}
I tried with CssSelector:
IWebElement logoutLabel = menu.FindElement(By.CssSelector(":contains('Sign Out')"));
IWebElement logoutLabel = menu.FindElement(By.CssSelector("label:contains('Sign Out')"));
IWebElement logoutLabel = menu.FindElement(By.CssSelector("label['Sign Out']"));
But these are not working.
There is a very good reason why your CSS selector wouldn't work, specifically the contains bit is where it falls over. Why?
It isn't part of the CSS selector specification, and therefore would never work.
The contains that we all know and love is actually coming from Sizzle, the CSS selector engine behind jQuery.
If you want text-based searching, you will either have to use XPath, or get a collection of those elements (using any locator you see fit) and then filter them down in code (like you have done in your foreach loop). There isn't a native CSS-style way to do "text based searching".
In terms of your current code, you will probably also fall over because XPath requires a little "poking" to tell it to search only the child elements of your current "element".
IWebElement menu = CurrentDriver.FindElement(By.CssSelector("div[class='menu-panel right']"));
IWebElement logoutLabel = menu.FindElement(By.XPath("//label[text()='Sign Out']"));
Should be:
IWebElement menu = CurrentDriver.FindElement(By.CssSelector("div[class='menu-panel right']"));
IWebElement logoutLabel = menu.FindElement(By.XPath(".//label[text()='Sign Out']"));
(Note the "." in the XPath)
Also, your foreach loop should have worked, therefore you will have to put a breakpoint in there and check exactly what is being returned by menu.FindElements(By.TagName("label"));.
You are using :contains(), which is a jQuery selector, not a CSS selector.
Apparently there is no way to achieve such thing using only CSS.
More info CSS selector based on element text?

How to handle StaleElementReferenceException when verifying a text?

I have a set of common methods which I run for each test. Like I need to add a few items in my cart and the whole test runs for each item. But for the first item it runs fine and when the process is repeated for the second item it fails while verifying a text and I get a StaleElementReferenceException.
How do I look up the item again or solve this ? Thanks.
Code where it fails:
public bool VerifyItemPresentInCart()
{
//Get the cartsize and verify if one item present
IWebElement cartSize = driver.FindElement(By.CssSelector("div[class='cart-size']>div"));
string actualMsg = cartSize.Text;
string expectedMsg = "1";
VerifyIfTextPresentMethod(expectedMsg,actualMsg);
return true;
}
Error at
IWebElement cartSize = driver.FindElement(By.CssSelector("div[class='cart-size']>div"));
Update: html code
<a class="header-button show-cart has-cart-items" data-view-name="cart-badge" data-view-cid="view5" data-model-cid="c6" data-tappable="true">
Cart
<div class="cart-size">
<div>3</div>
</div>
New code:
IWebElement cardDetails = driver.FindElement(By.CssSelector("div[class='form-field clear-fix']>label[for='cardNumber']>div"));
I would try joining your lines of code:
IWebElement cartSize = driver.FindElement(By.CssSelector("div[class='cart-size']>div"));
string actualMsg = cartSize.Text;
So that they are:
string actualMsg = driver.FindElement(By.CssSelector("div[class='cart-size']>div")).Text;
This means that the text will be retrieved on the element as it is selected. I am wondering if between getting a handle on the element via its parent and retrieving the text you are losing focus on that element. Alternatively, remove the >div from your css and see if it retrieves the text anyway.
This not working suggests the situation you are facing is the point under the title The Element is not Attached to the DOM. The fact that your target text is within only divs suggests that this area is being styled by javascript and thus may only be active at certain times. If this element is not active, but is accessible, you can still receive the StaleElementReferenceException, as indicated at that page. Your next step would be to see if you can click a parenting div to activate this target div prior to accessing its text (eg. make sure the element is attached to the DOM then call the code you have provided).

Categories