I have a bit of code that clicks on a link from a webpage which opens a new tab and automatically shifts my view to the new tab. When I try to select elements from that new webpage, I get errors saying the elements do no exist even though they do. Most of the times before the test crashes, the tab actually changes back to the original making me to believe that it is actually searching for the elements on the old tab. I try to use _driver.SwitchTo().Window(_driver.WindowHandles.Last()); in the hopes that it does something but it just closes out of the window entirely and opens a new blank window. How do I get it so I can get elements from the new webpage and no longer reference the old tab?
Use this helper function to switch to your tab of choice. The index is determined by the order they have been created. So your your default tabIndex is 0, if you open a new tab/window it will have tabIndex 1 and so forth..
internal void SwitchToTab(int tabIndex) {
WebDriver.Instance.Wait(2);
var newTab = WebDriver.Instance.Driver().WindowHandles[tabIndex];
Instance.Driver().SwitchTo().Window(newTab);
WebDriver.Instance.Wait(2);
}
The waits are just for letting the new tab load. These waits are not good practice, so you should look for other methods for waiting for whatever element/state you are waiting for.
Related
I'm creating app which is half-automated (user is opening tabs (attention) and if he wants to dump one of them he just clicks hot-key).
But when user opens to much tabs, I need to know to which one I should switch.
How can i get currenttab index. Or switch to current tab on Selenium C#?
string windowHandle = Browser.WindowHandles.Last();
string windowHandle = Browser.WindowHandles.First();
string windowHandle = Browser.WindowHandles[1];
...
is not working for me.
The currenttab index may get changed everytime you invoke Browser.WindowHandles().
Though the general perception is WindowHandles would be sorted like the oldest windows first and the newest windows last. But this is not the case: It is totaly random !
In a discussion, Simon clearly mentioned:
While the datatype used for storing the list of handles may be ordered by insertion, the order in which the WebDriver implementation iterates over the window handles to insert them has no requirement to be stable. The ordering is arbitrary.
This comment is pretty much inline with the Get Window Handles section where it mentioned:
In order to determine whether or not a particular interaction with the browser opens a new window, one can obtain the set of window handles before the interaction is performed and compare it with the set after the action is performed.
You can find a relevant detailed discussion in Best way to keep track and iterate through tabs and windows using WindowHandles using Selenium
Update
As per your comment user switch tab (in window) but driver is still focused on another tab you need to induce WebDriverWait for numberOfWindowsToBe(n) and you can find a detailed discussion in getWindowHandles() not working in firefox 58.The focus remains on parent tab and does not transfer to next tab
I am using a UltraTabbedMdiManager for a C# winform application. Each tab is added one at a time and displays a unique form. The tab panel is nested within its parent form. I am experiencing two issues related to new tab instantiation.
Issue #1: On adding a new tab the entire tab plane shifts down exposing a strip at the top of the parent form (Mdi container), just below its title bar. When clicking on another tab or elsewhere on the parent form, the tab plane reverts to its original position. This strip only appears on creating a new tab and disappears as soon as the focus is lost (by clicking elsewhere). It also occurs only every second tab that is generated which suggests an activation focus issue on new tabs. The problem does not occur when clicking between already generated tabs or when removing tabs.
I have found a work around for this issue: After the creation of the tab and its form, iterate through all the tabs in the mdi manager and disable them. This iteration is then immediately repeated with enabling all the tabs. The new tab is then reactived. These steps force a loss and then regain of focus and then activation of the tab (N.B. without activation the previous tab will be active). The following is a (verbose) piece of my code which does this operation:
var activeTab = MdiTabManager.ActiveTab;
foreach (var tabgroup in MdiTabManager.TabGroups)
{
foreach (var tab in tabgroup.Tabs)
{
tab.Form.Enabled = false;
}
}
foreach (var tabgroup in MdiTabManager.TabGroups)
{
foreach (var tab in tabgroup.Tabs)
{
tab.Form.Enabled = true;
}
}
activeTab.Activate();
Issue #2: On the generation of some new tabs. The form shifts down and the controls at the top of the previous tab are displayed (but are inactive) on the new tab. It is as if they were superimposed onto the new tab. A similar work around like before resolves this issue; I had read this on another infragistics forum post. However this time the tab's form ShowInTaskbar property is set to false and then true (after iterating through all the mdi managers tabs).
However, the workaround(s) have side-effects if relying on the Application.OpenForms collection. Calling ShowInTaskbar will effectively remove the open forms from this collection (a known Windows form bug as described here Application.OpenForms.Count = 0 always). Unfortunately my application relies on this collection. So my workaround is not applicable to my application. Though, it could be useful to other designs not relying on the OpernForms collection.
It is possible that the two issues are related. Perhaps solved in later version of infragistics. Infragistics does suggest upgrading. Before doing this has anyone experience such problems before?
Just for further information about our application. The form, that contains the mdi manager, is launched from our application's main form. This main form also uses a UltraTabbedMdiManager but does have these issues. Therefore are there known problems with having more than one mdi manager in the same project or solution ?
Here are my environment details:
Infragistics v14.1, .Net v4.7, Visual Studio 2017 Enterprise, C# 7.0, WinForms
When displaying a WPF window from an Excel addin, I'm encountering odd behaviour whenever I show it with myWindow.Show() rather than myWindow.ShowDialog(). Thus far everything has worked fine when using the latter. However, it would be nice to be able to display a window such that the user can interact with Excel at the same time - i.e. the behaviour I'd expect from Show().
The problem is that controls in my form start acting very oddly quite quickly. ComboBox dropdowns collapse immediately, and textbox input ends up in whatever cell is selected in the Excel worksheet that's active.
I've noticed that with ShowDialog, Snoop is able to attach to my window as well, whereas with Show, I get an error amounting to "Could not find a PresentationSource to attach to". I'm not, however, completely sure if that's related.
Obviously one solution would be to stop directly showing a WPF window from WinForms; I expect the problem to largely go away if I change my window into a UserControl and chuck it into an ElementHost. However, I'd rather avoid that if I can.
Current code (roughly)
public void DoOpenWindow(Office.IRibbonControl button)
{
var myWindow = new myWindow();
// This hasn't addressed the issue, though may be sensible to include:
//ElementHost.EnableModelessKeyboardInterop(myWindow);
// This *also* didn't work, and essentially set my window to
// be always on top of Excel
//var hwSrc = HwndSource.FromVisual(myWindow );
//var ownerHelper = new WindowInteropHelper(myWindow );
//ownerHelper.Owner = (IntPtr)Globals.ThisAddIn.Application.Hwnd;
// with ShowDialog() this works fine...
myWindow .Show();
}
Current thoughts are:
I'm getting window messages from Excel forwarded to myWindow, some of which it isn't expecting.
Excel is intercepting messages meant for my window (keyboard and mouse), which is probably what ElementHost.EnableModelessKeyboardInterop(myWindow) is intended to solve (but either I'm using it wrong, or it's not the whole solution).
I have a combo box which I need to mirror in another tab page in a C# winforms based application.
I have perfectly working code for when you select a different item from the drop down list. Unfortunately, however, when I change the Text of a tab that has not been clicked on yet nothing actually happens.
If I first click each tab then everything works as expected.
Now I'm putting this down to some form of lack of initialisation happening first. So I've tried to select each tab in my constructor.
tabControlDataSource.SelectedIndex = 0;
tabControlDataSource.SelectedIndex = 1;
// etc
But this doesn't work.
I've also tried calling tabControlDataSource.SelectTab( 1 ) and still it doesn't work.
Does anyone know how I can force the tab to "initialise"?
Ok, typically I post the question after struggling for an hour and shortly afterwards find the solution.
TabPages are lazily initialised. So they don't fully initialise until they are made visible for the first time.
So i added this code to my constructor:
tabControlDataSource.TabPages[0].Show();
tabControlDataSource.TabPages[1].Show();
tabControlDataSource.TabPages[2].Show();
but this didn't work :(
It occurred to me, however, that the constructor might not be the best place. So I created an event handler for Shown as follows:
private void MainForm_Shown( object sender, EventArgs e )
{
tabControlDataSource.TabPages[0].Show();
tabControlDataSource.TabPages[1].Show();
tabControlDataSource.TabPages[2].Show();
}
And now everything is working!
Perhaps you could also use sort of a "lazy" synchronization (initialization) in this case. Quick robust ideas: polling timer to update content (which will update it once you see tab page), no dependses within second tab (no Changed events for combobox to update second tab content, use original combobox from first tab or rather have it's content underlying in accessable for both comboboxes class, etc), "reinitialization" when tab become visible (at which moment you also init your second combobox)...
Can't be a hour, no way =D
Edit for those who say to use tab control
I would love to use a tab control; yet i have no idea how to go about linking the tab control up from the main form. I would assume that I would have to do something like this:
Create Form with a blank TabControl on it, no pages created.
Create a CustomuserControl (Add -> user Control), with my controls on it.
When a new chat comes in, create a tab control Item, Tab Control Page, add the Custom Control to the Tab Control Page. Add the tab control handle to the hash table, so that when new messages come in, they can be referenced in the proper control.
But, i am so not sure how to do this. For example, I know that I can create custom events inside of the User Control, so that, for example, if each control has a 'bold' button, i can each page that has that control on it, to actually USE the button.
Yet i also need to register message callbacks, so that I can use a MessageGrabber to send data to it, and tha'ts not assigned inside of the UserControl, that's assigned programatically when a new window comes in; but since I have no controls to reference, i can't assign.
KISS Philosophy
Wouldn't it be easier to just create the form, like i do now, and then just dock that form within a window or something? So that, in essence, it's still creating the form, but it's also a separate window?
Original Question
Okay, so i'm stumped (which isn't that big of a surprise when it comes to complex C# logic lol)! What i'm trying to do is the following:
Goal: Setup tabbed chatting for new chat application.
Completed: Open new window whenever a chat message is received, or a user requests a new chat from the roster. This is working perfectly, and opens only a window when the user doesn't already have the chat open. Nice and happy there.
Problem: I dont want windows. Well, i do want A window, but, i do not want tons of separate windows. For example, our Customer Service team may have about 10 active IM windows going at one time, i do not want them to have to have 10 windows tiled there lol. I'd rather they have a single Private IM window, and all 10 tabs docked within the window.
Logic: This is my logic here, which may be flawed, i do apologize:
OnMessage: Open new chat window if one doesn't already exist; if one exists, open it as a tab within the current chat window.
SendMessage: ^^ ditto ^^
Code Examples:
if (!Util.ChatForms.ContainsKey(msg.From.Bare))
{
RosterNode rn = rosterControl1.GetRosterItem(msg.From);
string nick = msg.From.Bare;
if (rn != null)
nick = rn.Text;
frmChat f = new frmChat(msg.From, xmpp, nick);
f.Show();
f.IncomingMessage(msg);
return;
}
Note on above: The Util. function just keeps tracks of what windows are opened inside of a hashtable, that way, when messages come in, they route to the proper window. That is added with the:
Util.ChatForms.Add(m_Jid.Bare.ToLower(), this);
Command in the frmChat() form.
Library in Use: agsxmpp from: http://www.ag-software.de/agsxmpp-sdk/download/
Problem:
How can i convert this code to open inside of tabs, instead of windows? Can someone please give me some ideas, and help with that. I just can't seem to wrap my head around that concept.
Use TabControl