Nested Hover in Selenium C# - c#

I am creating the test cases for my learning using Selenium C# in Orange Hrm application.
https://enterprise-demo.orangehrmlive.com/auth/login
Username and password: admin.
Once I login, there are differen menu, I am traversing through Admin>User Management>users and click on Users.
However, I am not getting way to how to use the MouseOver in Selenium C#.
Attached is the screenshot for your reference.enter image description here

From my limited knowledge you'll have to do it in a few steps.
Below is an example using NgWebDriver (angularJS app)
Actions builder = new Actions(ngDriver);
var elementToHover= ngDriver.FindElement(By.ClassName("dpcontract"));
builder.MoveToElement(elementToHover, 10 , 0)
builder.Build().Perform();
This builds a new action by finding the target element, moving the mouse to its position (x/y) with a 10 offset on the x (in my case).
You can add more events to that action trigger. The original (working) code for a drag and drop type-action i have is this
Actions builder = new Actions(ngDriver);
var elementToClick = ngDriver.FindElement(By.ClassName("dpcontract"));
builder.MoveToElement(elementToClick, elementToClick.Size.Width - 1, 0)
.ClickAndHold()
.MoveByOffset(150, 0)
.Release();
builder.Build().Perform();

Thank you Jens Stragier for your suggestion. Based on your suggestion, I wrote as follows and it worked for me.
Actions action = new Actions(Driver);
action.MoveToElement(elemWomen);
Thread.Sleep(500);
action.ClickAndHold(elemWomen);
action.Release(TShirt);
action.Click(TShirt);
action.Perform();

Related

How to specify ENTER button functionality in Selenium WebDriver code using C#

For practice sake, I'm writing test cases for irctc website, there I need to enter from station place and then respective stations with that code will be displayed as bootstrap dropdown and now i have to select one among them and click enter. Unfortunately there is no enter/submit button for from and to text field, please help me to continue with this test case
Here is my code
IWebElement Fromstn = driver.FindElement(By.XPath("//*[#id='divMain']/div/app-main-page/div/div/div[1]/div[1]/div[1]/app-jp-input/div/form/div[2]/div[1]/div[1]/span/i"));
Thread.Sleep(2000);
Fromstn.SendKeys("MAQ");
Fromstn.Click();
```**OR**
Actions builder = new Actions(driver); Actions hover = builder.MoveToElement(driver.FindElement(By.XPath("//*[#id='origin']"))); hover.Build().Perform(); Thread.Sleep(2000); hover.SendKeys("MAQ"); hover.Click();
from input try the below css :
p-autocomplete#origin input
To input try the below css :
p-autocomplete#destination input
Code :
driver.FindElement(By.CssSelector("p-autocomplete#origin input")).SendKeys("MAQ");
driver.FindElement(By.CssSelector("p-autocomplete#destination input")).SendKeys("some to station");
and if you wanna do Keyboard enter then probably use it with sendkeys():
something like this :
driver.FindElement(By.CssSelector("p-autocomplete#origin input")).SendKeys("MAQ" + Keys.RETURN);
See if this works:-
driver.FindElement(By.XPath("//label[text()='From']/..//input")).SendKeys("MAQ");
//Add a wait time for the drop down value to load
Actions builder = new Actions(driver);
Actions hover = builder.MoveToElement(driver.FindElement(By.XPath(".//ul[#id='pr_id_1_list']/li"))).Click().Perform();
You can try this code. For debugging see the Fromstn object in the quick watch and see if it has returned the correct element. for debugging you can also see the element is still in the form by 'inspect element' and do a find with the Xpath given when you are on the breakpoint.
IWebElement Fromstn = driver.FindElement(By.XPath("//*[#id='divMain']/div/app-main-page/div/div/div[1]/div[1]/div[1]/app-jp-input/div/form/div[2]/div[1]/div[1]/span/i"));
Thread.Sleep(2000); //you can also try by increasing the value for testing say 10 seconds
Fromstn.Clear();
Fromstn.SendKeys("MAQ");
Fromstn.Click();

How to get Selenium to operate two browser windows using only one driver selenium (using c# and chromedriver)?

I am attempting to control two browser windows via selenium using c# and a single chromedriver. The reason being that I need to share session details accross browser windows.
The code that I have tried and failed with is below;
var options = new ChromeOptions();
options.AddArguments("chrome.switches", "--disable-extensions --disable-extensions-file-access-check --disable-extensions-http-throttling --disable-infobars --enable-automation ");
options.AddUserProfilePreference("credentials_enable_service", false);
options.AddUserProfilePreference("profile.password_manager_enabled", false);
options.PageLoadStrategy = PageLoadStrategy.Default;
ChromeDriverService service = ChromeDriverService.CreateDefaultService();
service.HideCommandPromptWindow = true;
var Driver = new ChromeDriver(service, options);
//THIS WILL OPEN A NEW WINDOW. BUT BECAUSE IT IS A NEW DRIVER DOES NOT WORK FOR SHARING SESSION DETAILS.
//var TestDriver = new ChromeDriver(service, options);
//TestDriver.Manage().Window.Maximize();
//THIS JUST OPENS UP A NEW TAB. NOT A NEW WINDOW (IT WOULD SEEM MOST DOCUMENTATION SUGGESTS THAT IT SHOULD)
IJavaScriptExecutor jscript = Driver as IJavaScriptExecutor;
jscript.ExecuteScript("window.open();", "google.com.au");
//TRY USING THE SEND KEYS TECHNIQUE. NOTHING HAPPENS
var test = Driver.FindElement(By.TagName("html"));
test.SendKeys(Keys.Control + "n");
test.SendKeys(Keys.Control + "t");
//TRY AGAIN USING THE SEND KEYS TECHNIQUE USING A DIFFERENT TAG. NOTHING HAPPENS
var blah = Driver.FindElements(By.TagName("body"));
blah[0].SendKeys(Keys.Control + "t");
//TRY USING ACTIONS. NOTHING HAPPENS
Actions action = new Actions(Driver);
action.SendKeys(OpenQA.Selenium.Keys.Control + "n");
action.Build().Perform();
I may resort to AutoIt to open a browser if I have to, but one more dependency is not what I need. Documentation everywhere around the web seems to suggest than all the options I tried above should work...I suspect it may be a chromedriver issue of some kind.
Any ideas on how to achieve my goal would be greatly appreciated
UPDATE.
Arnons answer below lead me to the solution. If you are in a similar situation the best thing to do is just open up the browser console (from developers tools) and experiment with javascript until you get what you want. Then just execute that. In the end executing the following code has worked for me.
IJavaScriptExecutor jscript = Driver as IJavaScriptExecutor;
jscript.ExecuteScript("window.open('https://www.bing.com.au','_blank','toolbar = 0, location = 0, menubar = 0')");
The other alternative was to use Autoit, which I also got working, much easier than I did figuring out the javascript. But one less dependency is best :)
UPDATE2.
Further complications arise with trying to control the window as an independent browser window. I believe any new window created from a parent window, has the same process id (at least my testing has indicated so), and for all intense and purpose is treated as a tab in the selinium driver. I therefore conclude that certain things are just not possible (for example relocating the child browser window on the screen).
Your first attempt using ExecuteJavaScript was very close, but In order for it to open a new window instead of new tab, you should add the following arguments: `"_blank", "toolbar=0,location=0,menubar=0" to it.
See this question for more details.
I should have read the question better, here is my solution. Ended up using this for selecting windows that popped up after clicking a button but should work with swapping between windows.
//---- Setup Handles ----
//Create a Handle to come back to window 1
string currentHandle = driver.CurrentWindowHandle;
//Creates a target handle for window 2
string popupWindowHandle = wait.Until<string>((d) =>
{
string foundHandle = null;
// Subtract out the list of known handles. In the case of a single
// popup, the newHandles list will only have one value.
List<string> newHandles = driver.WindowHandles.Except(originalHandles).ToList();
if (newHandles.Count > 0)
{
foundHandle = newHandles[0];
}
return foundHandle;
});
//Now you can use these next 2 lines to continuously swap
//Swaps to window 2
driver.SwitchTo().Window(popupWindowHandle);
// Do stuff here in second window
//Swap back to window 1
driver.SwitchTo().Window(currentHandle);
// Do stuff here in first window
You need to explicitly tell Selenium which tab you wish to interact with, which in this case would be;
driver.SwitchTo().Window(driver.WindowHandles.Last());

Adding ChromeOptions for Selenium Webdriver C#

From what I understand, the default action of when the Webdriver finds an element is to scroll such that the element is as far up the top of the page as possible. This is an issue because the website I'm working on has a header so every time I try to click on a button, it will instead click on the header. Thus, I want to change the scroll setting so that the element will be at the bottom of the page.
From reading this I was able to find what I wanted to set, however, I'm unable to set the DesiredCapabilites or ChromeOptions when I initialise the ChromeDriver. Could some provide code/steps to do this please?
You can use something like this
var chromeOptions = new ChromeOptions();
chromeOptions.AddUserProfilePreference("intl.accept_languages", "en");
chromeOptions.AddUserProfilePreference("disable-popup-blocking", "true");
var driver = new ChromeDriver(chromeOptions);
Edit-2
If the option you want to set doesn't work for you then try using actions
var elem = driver.FindElements(By.Id("your element"));
Actions action = new Actions(driver);
action.MoveToElement(elem).Click(elem).Perform();//move to list element that needs to be hovered
Edit-3
If the above also doesn't work then your next option is to use Javascript
var elem = driver.FindElements(By.Id("your element"));
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
var success = js.ExecuteScript("arguments[0].click(); return true", elem);
As far as I know you can't change everything through addarguments.
There is a list of what you can do in the Github page. but I have a better solution. you can make your own default settings and save it as a chrome profile. for example I didn't find anything to change homepage with code but this works fine for almost evwerything.
you can use this code :
options.AddArguments( #"user-data -dir=C:\Users\kian\AppData\Local\Google\Chrome\User Data");
options.AddArgument("--profile-directory=Default");
make sure you write the right path and right profile name.
to check the profile name you can go to properties.
properties
you will see the profile name.
there is a good guide for what else u can do in link.

How to generate keyboard text for the active process of Firefox

I can send a text from my C# WinForm app to another application like Notepad using:
SendKeys.SendWait("Hello");
but I need to send text to an html input element in Firefox. There are several ways to select a target application. This SO Question uses code like:
Process p = Process.GetProcessesByName("notepad").FirstOrDefault();
IntPtr h = p.MainWindowHandle;
SetForegroundWindow(h);
to set the desired app to the foreground so it will receive the text. But this does not work with the app named "firefox", probably because it uses not 1 but 4 processes according to the Task Manager.
I tried another approach: right before calling SendKeys.SendWait, just switch back to the last active application just like Alt-Tab does, using code from this SO Question, which works for Notepad, and for the Chrome browser, but not for Firefox.
The purpose of this is to get data from a weight measurement device (scale), connected to the RS232 port, to the html input element in the browser. The same principle of simulating a keyboard is routinely used with USB barcode scanners.
Any idea how to do this with Firefox?
Am I perhaps on the wrong track, and are there perhaps much different methods to get text in the keyboard?
Can't you use WinForms WebBrowser? Also consider using Selenium WebDriver which is available via Nuget. I think it does exactly what you need.
That's an example from docs:
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
// Requires reference to WebDriver.Support.dll
using OpenQA.Selenium.Support.UI;
class GoogleSuggest
{
static void Main(string[] args)
{
// Create a new instance of the Firefox driver.
// Note that it is wrapped in a using clause so that the browser is closed
// and the webdriver is disposed (even in the face of exceptions).
// Also note that the remainder of the code relies on the interface,
// not the implementation.
// Further note that other drivers (InternetExplorerDriver,
// ChromeDriver, etc.) will require further configuration
// before this example will work. See the wiki pages for the
// individual drivers at http://code.google.com/p/selenium/wiki
// for further information.
using (IWebDriver driver = new FirefoxDriver())
{
//Notice navigation is slightly different than the Java version
//This is because 'get' is a keyword in C#
driver.Navigate().GoToUrl("http://www.google.com/");
// Find the text input element by its name
IWebElement query = driver.FindElement(By.Name("q"));
// Enter something to search for
query.SendKeys("Cheese");
// Now submit the form. WebDriver will find the form for us from the element
query.Submit();
// Google's search is rendered dynamically with JavaScript.
// Wait for the page to load, timeout after 10 seconds
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => d.Title.StartsWith("cheese", StringComparison.OrdinalIgnoreCase));
// Should see: "Cheese - Google Search" (for an English locale)
Console.WriteLine("Page title is: " + driver.Title);
}
}
}

CAD insert block with thumbnail under mouse

I need to insert an external DWG into an AutoCAD drawing via C# plugin.
I need to "ask" to the user the insertion point and rotation of the inserted block.
Until now I've always used a lisp function that calls the command "._-insert" which gives a thumbnail of the block under the mouse, allows the user to click into the drawing to set the insertion point and from that point allows the user to click one more time to set the rotation.
Now I want to avoid the use of Lisp or the use of low level API of AutoCAD because I need a solution that runs over various CAD environments.
What I found is something like this:
public static void InsertDwg(string dwgName)
{
CADAPI.ApplicationServices.Document doc = CADAPI.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
CADDB.Database db = doc.Database;
CADAPI.EditorInput.Editor ed = doc.Editor;
CADDB.ObjectId ObjId;
using (CADDB.Transaction trx = db.TransactionManager.StartTransaction())
{
CADDB.BlockTable bt = db.BlockTableId.GetObject(CADDB.OpenMode.ForRead) as CADDB.BlockTable;
CADDB.BlockTableRecord btrMs = bt[CADDB.BlockTableRecord.ModelSpace].GetObject(CADDB.OpenMode.ForWrite) as CADDB.BlockTableRecord;
using (CADDB.Database dbInsert = new CADDB.Database(false, true))
{
dbInsert.ReadDwgFile(dwgName, CADDB.FileOpenMode.OpenForReadAndAllShare, true, string.Empty);
ObjId = db.Insert(Path.GetFileNameWithoutExtension(dwgName), dbInsert, true);
}
CADAPI.EditorInput.PromptPointOptions ppo = new CADAPI.EditorInput.PromptPointOptions("\nInsertion Point");
CADAPI.EditorInput.PromptAngleOptions ppa = new CADAPI.EditorInput.PromptAngleOptions("\nInsert Rotation");
CADAPI.EditorInput.PromptPointResult ppr;
ppr = ed.GetPoint(ppo);
CADAPI.EditorInput.PromptDoubleResult ppd = ed.GetAngle(ppa);
if (ppr.Status == CADAPI.EditorInput.PromptStatus.OK)
{
CADGEOM.Point3d insertPt = ppr.Value;
CADDB.BlockReference bref = new CADDB.BlockReference(insertPt, ObjId);
btrMs.AppendEntity(bref);
trx.AddNewlyCreatedDBObject(bref, true);
trx.Commit();
}
}
}
But here I have two problems:
The main one is that there is no preview under the mouse.
The second is that the user needs to click 3 times instead of 2 to set both the insertion point and the rotation.
Is there any way that doesn't use some kind of SendCommand and does all of this stuff?
TIA
It seems Jigging is the way to go to allow the preview. I have three links for you.
Jigging multiple entities with the DrawJig
Using a jig to rotate an AutoCAD entity via .NET
Using transient graphics to simulate AutoCAD’s MOVE command using .NET
The first is an example of creating a simple jig with polylines - you could extend this to a block.
The second link is similar but applies rotation to the mix. This is applied to a rectangle but again could be modified to accomodate a block.
The third link describes a different method - AutoCADs transient graphics interface. You must be using AutoCAD 2009 or later to use this method.
The last two links are from the Through the Interface blog, where you may find some more examples and is a very good starting point if you have problems, especially for coding C#.
You will want to use the AcEdJig class. It provides the preview. You will have to write the code to collect the insert point and rotation and to transform the block accordingly.
Here is the first link from my google search for example usage code.

Categories

Resources