What is the difference between WebDriver.SwitchTo().Window() and WebDriver.SwitchTo().Frame() - c#

A few days ago, I had the requirement to make my WebDriver(Chromedriver in that case) switch between 2 tabs on my browser (One of which has been automatically opened by clicking a link).
I was able to implement a solution using the following lines (C#)
var tabs = new List<String>(Driver.WindowHandles);
//Switches to the first tab
Driver.SwitchTo().Window(tabs[0]);
However, I recently came across some implementations that use frames and alerts, which confused me.
The documentation has not been very helpful to me as I still have trouble figuring out use cases for each.
Could you please enlighten me what the difference between Frame and Window is for that purpose ( performance, reliability, cross-platform,... )?

Frame :
is a tag in HTML. However The tag is not supported in HTML5.
The <frame> tag defines one particular window (frame) within a <frameset>
Normally, You must have seen Iframe in DOM. It's basically section of a HTML page.
Moreover, If you want to interact any element which is inside a frame , You will have to switch to frame.
How :
SwitchTo().Frame(int frameIndex) : using index
SwitchTo().Frame(IWebElement frameElement) : Select a frame using its previously located OpenQA.Selenium.IWebElement.
SwitchTo().Frame(string frameName) : Select a frame by its name.
Windows :
When you click on any any link and a new tab opens or a new windows itself open that's a window in Selenium.
How : You have already mentioned that in your Post.
Hope this'll be helpful.

In Selenium, Window can be different Tab in same browser instance or different browser instance. The context of switch to window is multiple pages or browser instance.
Frame inside web page, so the context of switch to frame is one Page, not multiple pages or browser instances.

Window Object
The Window Object represents an open window in a browser.
If a document contain frames ( tags), the browser creates one Window Object for the HTML document and one additional window object for each of the frame it contains.
As per the WebDriver W3C Editor's Draft WebDriver commands happen in the context of either the current browsing context or the current top-level browsing context.
Driver.SwitchTo().Window(windowHandle)
The current top-level browsing context is represented in the protocol by its associated window handle. A top-level browsing context can be selected using the Switch To Window command as follows :
Driver.SwitchTo().Window(windowHandle)
Driver.SwitchTo().Frame(frameReference)
Similarly, a specific browsing context can be selected using the Switch to Frame command.
Driver.SwitchTo().Frame(driver.FindElement(By.XPath("//iframe[contains(#src,'<src_attribute_value>')]")));

Related

Webdriver access elements of a page which is embedded in div of parent page

We have a page(URL 2) which is embedded or loaded in Div element(Popup) of another page(master page) when a button is clicked on master page(URL 1).
I am not able to access the elements on this embedded page.
The firepath developer plugin shows, there are two objects (Top Window URL 1 and another with different URL 2). When I try to highlight any element with xpath locator on page 2 URL 2, its not successful as the object/document selected is Top Window. In order to access elements on page 2, the document needs to be changed.
Tried using SwitchTo method but no luck. The embedded page is niether loaded in a separate window nor in Iframe.
SwitchTo method can only be used if another window is opened or Iframe is present on page.
Does anyone have any ideas or solutions to change the document context so that all new commands are sent to this new page 2.
I am using C# bindings v2.53.
Thanks in advance.
Try to use:
driver.SwitchTo().Window(driver.WindowHandles.ToList().Last());
I got the problem and eventually answer to that.
Its really simple. Its simply working out with jquery.
{driver.executeScript("return $('body /deep/ <#yourSelector>')}
this piece of code simply draws the element from shadow DOM and which can be further used to simulate user actions... :)

C# Setting InnerHtml to "" for an element which is updated by server causes element to stop updating

I have a C# Windows Forms Application with a webBrowser within it. It visits a Wikia chatroom, where it then locates the element which contains the chat output. This element looks like:
<div style="" id="Chat_XXXXX" class="Chat">
<ul>
(chat text)
</ul>
</div>
The purpose of the program is to retrieve the chat text every once in a while for logging purposes. This is easily done by parsing the "InnerHtml" of the "Chat_XXXXX" element. However, I also need to clear the text from the window when I do this (for various reasons, I cannot leave the text in the window). I figured I would just erase the chat text portion of the element, as this is how it is done with a handy javascript file called "chat hacks" for Wiki chat (here). Or at least, I think that's how it does it. If you look at the function "clearWindow" in that file, you can see what it does:
NodeChatController.prototype.clearWindow = function() {
this.viewDiscussion.chatUL.html('');
this.inlineAlert(i18n['cleared']);
}
I have tried setting the InnerHtml of "Chat_XXXXX" using the following three strings (not all at the same time, of course):
HtmlDocument document = webBrowser1.Document;
document.GetElementById("Chat_XXXXX").InnerHtml = ""
document.GetElementById("Chat_XXXXX").InnerHtml = "<ul></ul>"
document.GetElementById("Chat_XXXXX").InnerHtml = "<ul><li class=\"inline-alert\"> Window cleared. </li></ul>"
However, although these clear the window (and in the case of the last one prints a message), the chat no longer updates as new messages show up. The only fix is to reload the page, which isn't an option, because reloading the page brings in a whole load of chat history (which I'm trying to avoid). I've also tried importing that javascript mentioned above into the page using:
HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
scriptEl.SetAttribute("type", "text/javascript");
scriptEl.SetAttribute("src", "https://db.tt/66q8UQbY");
head.AppendChild(scriptEl);
This javascript creates a button which clears the chat window. The button clears the window just fine, but again, the chat no longer updates. I know this button works correctly without stopping further incoming chat in "regular" browsers (Chrome, Firefox, Opera, etc). I've used it many times, and the script itself is quite popular in the Wikia community. I've already followed the steps here: "WPF WebBrowser Control - position:fixed Element jumps while scrolling (Windows 8)" to get the browser to act as close as it can (?) to Internet Explorer. I've already checked the Body field of the document after altering the InnerHtml to make sure that my replacements didn't alter anything important. Just for clarity, here's an example of what is contained in the (chat text) portion of my original example:
<li class="you" data-user="UserNameHere" id="entry-c812">
...avatars and junk...
<span class="message">hello</span>
</li>
I honestly have no idea what could be causing the chat element to stop updating after it has been edited (especially since it works outside of this program), so I don't know what information to include. Whatever you need, I'll provide it. Here's the javascript from Wikia which generates the chat output window: chat_js2. Look for "Chat_" to find the part which originally generates the window. I don't know where the output is updated in that file though.

Ranorex test automation issue: Unable to reliably click a button on silverlight web app

We have automated a few test cases using the Ranorex automation framework for a Silverlight web application. These test cases involve clicking buttons in order to invoke certain messages on the screen. In order to grab the button on the screen, we first create an Ranorex button object and then point it to the appropriate element using Ranorexpath. Then, we use the RanorexButton.Click() event to click the button. However, this event is unreliable. It works sometimes and at other times the button is not clicked. When the button is not clicked, we have to run the test case again from the start. What are we doing wrong? If this is a known problem of ranorex, please suggest workarounds.
I was facing the same problem but I am able to resolve the problem by introducing a Validate.Exists(infoObject) just before the click. Please make sure that you pass infoObject of your button or any element in Validate.Exists API.
Example:
Validate.Exists(repo.MyApp.LoginBtnInfo);
var button = repo.MyApp.LoginBtn;
button.Click();
With regards,
Avinash Nigam
I haven't heard about such a problem with Ranorex yet, maybe this is just a timing issue.
You could add a Validate.Exists(yourButton) right before the click, this ensures that the click is performed after the button was successfully loaded.
If it is a WebElement you could also use the PerformClick() method instead of the normal Click() method.
There are also different methods which will ensure that the button is in the visible area and has focus, like the EnsureVisible() or the Focus() method.
You will find the available methods of the used adapter in the online API of Ranorex.
If the Button is not within the area you can see without scrolling, you can use a
var button = repo.Buttons.button1;
button.EnsureVisible();
button.Click();
In this way the button is forced to be watched.
It might as well be an issue with the xpath and element Id-s.
If you have changing element Id-s even when the page is navigated away from and moved back (for example we have this issue with SAP related components) you might need to make a more robust xPath path variable using regular expressions.
Try to find object and parts of the path that do not change (eg. "iFrame id="MainContent"" or "btn id="ID_XXXX_Search_Button"") - ofcourse this will only help if the issue is within this.
Ranorex Regular Expression info can be found here: http://www.ranorex.com/support/user-guide-20/ranorexpath.html#c3294
A quick example of what I'm talking about:
Let's say we have an input field that has a changing ID in it's name:
US_EL.ID_F2B49DB60EE1B68131BD662A21B3432B:V_MAIN._046A-r
And I know that the part in the Id that doesn't change is:
:V_MAIN._046A-r
I can create a path for this searching the element by the ending of the elements' id that doesn't change using regular expression:
/dom[#domain='test.example.com']//iframe[#'identifier']//iframe[#'identifier2']//input[#id**~'^**:V_MAIN._046A-r']
The bold part will specify to search for an input element with an Id that ends with ":V_MAIN._046A-r".
An issue that might arrise from this is if you have elements using partially the same names you might get multiple elements returned for the same path. So it's wise to add a few more certain points to the path (eg. "iframe[#'identifier2']") when this issue arrises.

How to send data to a page navigated to through the Frame.Navigate in Silverlight 4

Platform:
Silverlight 4 / .NET 4
Background:
I have a page that consists of two parts. The left part is a tree view, the right one is the content area. When I select a tree item, an appropriate UserControl page should be loaded in the right part of the page, depending on the type of the tree item.
I am using a Frame object, defined in XAML.
When a user selects a tree view item, I resolve the item's type and then I navigate to the page defined for that type.
However, Frame.Navigate is an asynchronous method so if I try to get the frame's content after Navigate, the frame has not navigated yet, so I either get nothing or the last loaded page.
contentFrame.Navigate(new Uri("/PageA.xaml", UriKind.Relative));
PageA page = contentFrame.Content as PageA;
// page here is either null or a previously opened page
Problem:
I need to send some data (stored in treeview item's Tag) to the page being navigated to and the only Frame.Navigate overload is asynchronous (without callback). How can I send some data to the navigated page? Is there any other technique for accomplishing what I need?
You can use the NavigationService provided by Silverlight. It has query string support using which you can build RESTful URI. I am assuming that you need to pass some context based data to the landing page. Following links might help you
http://www.silverlightshow.net/items/The-Silverlight-3-Navigation-Framework.aspx
http://blogs.microsoft.co.il/blogs/alex_golesh/archive/2009/04/02/silverlight-3-quick-tip-6-navigation-framework-and-uri-routing.aspx
http://www.wintellect.com/CS/blogs/jprosise/archive/2009/04/07/silverlight-3-s-new-navigation-framework.aspx
Although the links says Silverlight 3, these features are supported in Silverlight 4 as well.
You definitely want to use some flavor of the M-V-VM pattern that Nilesh suggested.
I guess you could also have a static class that holds static references of objects.
You can simply refer to static objects here when your frames have completed their event (e.g. NavigatedTo).

Get the links id for the current cursor position in the webrowser control

We are using the WebBrowser control in c# winforms and need to be able to get information about the Url the cursor is positioned on.
So we have a web page in design mode, which has multiple urls, when the cursor is over one I would like to call a method which would return the id of the link.
Thanks
You can use the IHTMLCaret to get the cursor position from there using IMarkupPointer you can get the element in the current scope.
The webBrowser control has a Document property which has a Links collection. Each Link is an HTMLElement which has events you can tap into. Again, I'm not sure what you mean "cursor" because in the web world, unless if you're in a textbox, there really isn't a "cursor" (which is what I meant to ask in my comment) but you can tap into the MouseOver event and other stuff like that.
Example:
foreach (HtmlElement element in this.webBrowser1.Document.Links)
{
element.MouseOver += (o, ex) =>
{
Console.WriteLine(ex.ToElement.GetAttribute("HREF"));
};
}
This will print out the actual URL that the mouse is over.
You can have a look at this article - Hosting a web browser component in a C# winform - which explains several ways to perform that. or go directly to this one - Hosting a webpage inside a Windows Form - Basically what you need to do is handle the Click of the DOM object inside the COM WebBrowser of IE. You achieve this by handling the Js events inside your C# code.
I remember this kind of customization must be done using the AxSHDocVw.AxWebBrowser COM object instead of the System.Windows.Forms.WebBrowser Class from the newer versions of the .Net Framework.
I could send you more data about this, I did it some project, just give me time to find it ;). In the mean time try with those links.
By!

Categories

Resources