MoveByOffset does not work in selenium - c#

I have a canvas and there i need to move the mouse from one point to another point to draw a rectangle. CapabilityType.HasNativeEvents is set to false. I'm using IE11 and .Net. The issue is while using selenium grid in continuous integration machine but works fine in local .
I tried this but it does not work. Any clue?
Actions builder = new Actions(_webDriver);
builder.MoveToElement(Canvas, 800, 250).Click().Build().Perform();
System.Threading.Thread.Sleep(2000);
builder.ClickAndHold(Canvas).MoveByOffset(500, -30).Build().Perform();

Related

Get HTML display area (viewport) offset to 0/0 and zoom of IE window using .NET/C# and SHDocVw.InternetExplorer

THIS IS NOT A HTML / JAVASCRIPT / CSS question!
Check out these images:
I need to get the HTML display area (aka viewport) offset to the 0/0 of the IE window.
I am targeting Microsoft Internet Explorer 11.
I am using C# with SHDocVw.InternetExplorer library to access/control the IE.
What I actually want to do is to trigger double-click events
similar to IHTMLElement.click(), just a doubleClick()
calling IHTMLElement.click() multiple times does not work
I tried to solve it WITHOUT actually clicking:
How to make SHDocVw.InternetExplorer fire events that get caught with JS addEventListener?
but that has not received any answers yet
So right now I'm controlling the mouse to trigger certain events, calling [DllImport("user32.dll")] public static extern bool GetCursorPos(out PointInter lpPoint); and the like to get and set the mouse cursor and to simulate double-clicks on certain elements.
For the mouse navigation I already take into consideration
the OS's desktop zoom/scale setting
the IE window Left and Top properties
the location of the IHTMLElement(3).getClientBoundingRect, i.e. the position of the element I wanna trigger
This all works perfectly fine when the IE configuration is the same. My assumptions:
same HTML viewport offset (same toolbars, menus etc)
HTML viewport scaling 100% (no page zooming)
But those two factors are dynamic, so I have to account for them in some way.
So what I need is:
The HTML viewport's vertical offset (in both screenshots it's 106 pixels)
The HTML viewport's horizontal offset (in first its 1, in second it's 291)
The HTML viewport's zoom factor (in both screenshots 100%)
I have tried accessing multiple elements in the ShDocVw.InternetExplorer object, but I either have the wrong interface casts or it does not expose this information willingly, because I could not find it yet.
From a delve into the google world I also came up empty, so no (obvious) answers there either.
So does any one of you know how to deal with this problem? Some obscure COM/OLE incantations and rituals that could guide the mouse cursor on its way?
EDIT:
Dirty solution: I could display some homemade HTML/JS page first, that detects my simulated mouse movement and dump that information into some (invisible) div, then read that data in C#.
Though this is a solution, it's quite ugly and not useful for taking into account layout/display changes that might occur during later runtime, if user changes zooms while the app is working.

Testing swipe on responsive website using Selenium Webdriver C#

I'm trying to test a swipe across an image gallery on a responsive website. On a mobile device it would be a finger swipe, using a desktop browser it functions the same with a mouse click/hold/drag. It's the desktop browser functionality I'm trying to replicate.
The code I have is:
Driver.Navigate().GoToUrl(Properties.Settings.Default.TestPage);
var mainImage = Driver.FindElement(By.CssSelector(".main-image"));
var imageAcross = (mainImage.Size.Width / 4 ) * 3;
var imageDown = mainImage.Size.Height/2;
var builder = new Actions(Driver);
builder.MoveToElement(mainImage, imageAcross, imageDown).ClickAndHold().Build().Perform();
TakeScreenshot(TestContext.CurrentContext.Test.Name);
builder.MoveByOffset(-imageDown, 0).Release().Build().Perform();
TakeScreenshot(TestContext.CurrentContext.Test.Name);
The TakeScreenshot function, as the name suggests, saves a screenshot. I take one before and after the move.
The first builder.MoveToElement places the cursor where I would expect and after the builder.MoveByOffset the cursor has moved as expected. However the swipe didn't change the gallery image. It's as if the ClickAndHold was ignored.
The CSS element .main-image is a div tag that has Javascript attached that changes an image within it on the swipe. The browser I'm using for testing is PhantomJS.
Is there something I am doing wrong? Or any suggestions on how to get the swipe to work?

Selenium C# PhantomJs can't change viewport height

i have Problem setting up Viewport on PhantomJS using Selenium.
webDriver.Navigate().GoToUrl("http://detectmybrowser.com/");
webDriver.Manage().Window.Size = new Size(1920, 1080);
webDriver.TakeScreenshot().SaveAsFile("screenshot.png", ImageFormat.Png);
But when i check my browser resolution on detectmybrowser i get a resolution of 1920x4128.
Look
I tryed to maximize the window but this didn't change anything. Please help :)
PhantomJS automatically expands the viewport in the scroll direction. It should report the configured viewport height when requesting document.viewport.getHeight() (as used on the site you're on), but it reports the expanded height. Another way to get the proper viewport height would be through document.documentElement.clientHeight and window.innerHeight.

Drawing to screen directly on top of all window [duplicate]

I want to draw directly on the desktop in C#. From searching a bit, I ended up using a Graphics object from the Desktop HDC (null). Then, I painted normally using this Graphics object.
The problem is that my shapes get lost when any part of the screen is redrawn. I tried a While loop, but it actually ends up drawing as fast as the application can, which is not the update rate of the desktop.
Normally, I would need to put my drawing code in a "OnPaint" event, but such thing does not exist for the desktop.
How would I do it?
Example code: https://stackoverflow.com/questions/1536141/how-to-draw-directly-on-the-windows-desktop-c
I posted two solutions for a similar requirement here
Basically you have two options.
1- Get a graphics object for the desktop and start drawing to it. The problem is if you need to start clearing what you have previously drawn etc.
Point pt = Cursor.Position; // Get the mouse cursor in screen coordinates
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
{
g.DrawEllipse(Pens.Black, pt.X - 10, pt.Y - 10, 20, 20);
}
2- The second option that I provide in the link above is to create a transparent top-most window and do all your drawing in that window. This basically provides a transparent overlay for the desktop which you can draw on. One possible downside to this, as I mention in the original answer, is that other windows which are also top-most and are created after your app starts will obscure your top most window. This can be solved if it is a problem though.
For option 2, making the form transparent is as simple as using a transparency key, this allows mouse clicks etc. to fall through to the underlying desktop.
BackColor = Color.LightGreen;
TransparencyKey = Color.LightGreen;
When you draw to HDC(NULL) you draw to the screen, in an unmanaged way. As you've discovered, as soon as windows refreshes that part of the screen, your changes are overwritten.
There are a couple of options, depending upon what you want to achieve:
create a borderless, possibly
non-rectangular window. (Use
SetWindowRgn to make a window
non-rectangular.) You can make this a child of the desktop window.
subclass the desktop window. This is not straightforward, and involves
injecting a DLL into the
Explorer.exe process.
To get an OnPaint for the desktop you would need to subclass the desktop window and use your drawing logic when it receives a WM_PAINT/WM_ERASEBKGND message.
As the thread you linked to says, you can only intercept messages sent to a window of an external process using a hook (SetWindowsHookEx from a DLL).
As mentioned a transparent window is another way to do it, or (depending on the update frequency) copying, drawing and setting a temporary wallpaper (as bginfo does).
This is difficult to do correctly.
It will be far easier, and more reliable, to make your own borderless form instead.

rectangle drawn on desktop is not persistent in c# [duplicate]

I want to draw directly on the desktop in C#. From searching a bit, I ended up using a Graphics object from the Desktop HDC (null). Then, I painted normally using this Graphics object.
The problem is that my shapes get lost when any part of the screen is redrawn. I tried a While loop, but it actually ends up drawing as fast as the application can, which is not the update rate of the desktop.
Normally, I would need to put my drawing code in a "OnPaint" event, but such thing does not exist for the desktop.
How would I do it?
Example code: https://stackoverflow.com/questions/1536141/how-to-draw-directly-on-the-windows-desktop-c
I posted two solutions for a similar requirement here
Basically you have two options.
1- Get a graphics object for the desktop and start drawing to it. The problem is if you need to start clearing what you have previously drawn etc.
Point pt = Cursor.Position; // Get the mouse cursor in screen coordinates
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
{
g.DrawEllipse(Pens.Black, pt.X - 10, pt.Y - 10, 20, 20);
}
2- The second option that I provide in the link above is to create a transparent top-most window and do all your drawing in that window. This basically provides a transparent overlay for the desktop which you can draw on. One possible downside to this, as I mention in the original answer, is that other windows which are also top-most and are created after your app starts will obscure your top most window. This can be solved if it is a problem though.
For option 2, making the form transparent is as simple as using a transparency key, this allows mouse clicks etc. to fall through to the underlying desktop.
BackColor = Color.LightGreen;
TransparencyKey = Color.LightGreen;
When you draw to HDC(NULL) you draw to the screen, in an unmanaged way. As you've discovered, as soon as windows refreshes that part of the screen, your changes are overwritten.
There are a couple of options, depending upon what you want to achieve:
create a borderless, possibly
non-rectangular window. (Use
SetWindowRgn to make a window
non-rectangular.) You can make this a child of the desktop window.
subclass the desktop window. This is not straightforward, and involves
injecting a DLL into the
Explorer.exe process.
To get an OnPaint for the desktop you would need to subclass the desktop window and use your drawing logic when it receives a WM_PAINT/WM_ERASEBKGND message.
As the thread you linked to says, you can only intercept messages sent to a window of an external process using a hook (SetWindowsHookEx from a DLL).
As mentioned a transparent window is another way to do it, or (depending on the update frequency) copying, drawing and setting a temporary wallpaper (as bginfo does).
This is difficult to do correctly.
It will be far easier, and more reliable, to make your own borderless form instead.

Categories