How do I get Selenium WebDriver to scroll to a particular element to get it on the screen. I have tried a lot of different options but have had no luck.
Does this not work in the C# bindings?
I can make it jump to a particular location ex
((IJavaScriptExecutor)Driver).ExecuteScript("window.scrollTo(0, document.body.scrollHeight - 150)");
But I want to be able to send it to different elements without giving the exact location each time.
public IWebElement Example { get { return Driver.FindElement(By.Id("123456")); } }
Ex 1)
((IJavaScriptExecutor)Driver).ExecuteScript("arguments[0].scrollIntoView(true);", Example);
Ex 2)
((IJavaScriptExecutor)Driver).ExecuteScript("window.scrollBy(Example.Location.X", "Example.Location.Y - 100)");
When I watch it, it does not jump down the page to the element, and the exception matches the element being off screen.
I added an bool ex = Example.Exists(); after it and checked the results.
It does Exist (its true).
Its not Displayed (as its still offscreen as it has not moved to the element)
Its not Selected ??????
Someone is seeing success By.ClassName.
Does anyone know if there is a problem with doing this By.Id in the C# bindings?
Its little older question, but I believe that there is better solution than suggested above.
Here is original answer: https://stackoverflow.com/a/26461431/1221512
You should use Actions class to perform scrolling to element.
var element = driver.FindElement(By.id("element-id"));
Actions actions = new Actions(driver);
actions.MoveToElement(element);
actions.Perform();
This works for me in Chrome, IE8 & IE11:
public void ScrollTo(int xPosition = 0, int yPosition = 0)
{
var js = String.Format("window.scrollTo({0}, {1})", xPosition, yPosition);
JavaScriptExecutor.ExecuteScript(js);
}
public IWebElement ScrollToView(By selector)
{
var element = WebDriver.FindElement(selector);
ScrollToView(element);
return element;
}
public void ScrollToView(IWebElement element)
{
if (element.Location.Y > 200)
{
ScrollTo(0, element.Location.Y - 100); // Make sure element is in the view but below the top navigation pane
}
}
This works for me:
var elem = driver.FindElement(By.ClassName("something"));
driver.ExecuteScript("arguments[0].scrollIntoView(true);", elem);
This works for me in C# automation:
public Page scrollUp()
{
IWebElement s = driver.FindElement(By.Id("your_locator")); ;
IJavaScriptExecutor je = (IJavaScriptExecutor)driver;
je.ExecuteScript("arguments[0].scrollIntoView(false);", s);
return this;
}
I created a extension for IWebDriver:
public static IWebElement GetElementAndScrollTo(this IWebDriver driver, By by)
{
var js = (IJavaScriptExecutor)driver;
try
{
var element = driver.FindElement(by);
if (element.Location.Y > 200)
{
js.ExecuteScript($"window.scrollTo({0}, {element.Location.Y - 200 })");
}
return element;
}
catch (Exception ex)
{
return null;
}
}
For scroll down inside the page here I have small code and solution
My Scenario was until I scroll down the page. Accept and Don't accept button was not getting enabled. I was having 15 terms and conditions from which I needed to select 15th term and condition by inspecting webpage and taking the Id of last terms and condition paragraph.
driver.FindElement(By.Id("para15")).Click();
<div id="para15">One way Non-Disclosure Agreement</div>
I had somehow same problem. I was working on a web page and need to click on a button on a child window which by default, was located below screen.
This is the code I used and it worked.
Actually I just simulated a mouse drag and drop and moved the window 250 points upwards so that the button was in the screen.
Actions action = new Actions(driver);
action.DragAndDropToOffset(driver.FindElement(By.XPath("put an element path which **is in the screen now**, such as a label")), 0, -250);
action.Build().Perform();
If the reason we put time is for a long time to load the page, we put it. Just it.
ChromeOptions options = new ChromeOptions();
var driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.w3schools.com/");
Thread.Sleep(5000);
driver.ExecuteScript("scroll(0,400)");
HtmlDocument countriesDocument = new HtmlDocument();
countriesDocument.LoadHtml(driver.PageSource);
I am providing solution to scroll within a specific element, like a scrollable table.
// Driver is the Selenium IWebDriver
IJavaScriptExecutor exec = (IJavaScriptExecutor) Driver;
int horizontalScroll= direction == Direction.Right ? X : 0;
int verticalScroll = direction == Direction.Down ? Y : 0;
exec.ExecuteScript(
"arguments[0].scrollBy(arguments[1], arguments[2])"
, Self
, horizontalScroll
, verticalScroll);
Actions actions = new Actions(driver);
actions.SendKeys(Keys.PageDown).Build().Perform();
You do it through for, it works like clockwork, simple, but not always convenient
var js = (IJavaScriptExecutor)driver;
js.ExecuteScript("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'})", PutYourElementIDHere);
var e = driver.FindElement(By.XPath("//*[text()='Timesheet']"));
// JavaScript Executor to scroll to element
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView(true);", e);
This may be a noobish question, but in my records in Coded UI Tests, I have recorded a lot of controls that don't have enough defined properties to be found in playback.
For exemple:
public HtmlEdit UIItemEdit
{
get
{
if ((this.mUIItemEdit == null))
{
this.mUIItemEdit = new HtmlEdit(this);
#region Search Criteria
this.mUIItemEdit.SearchProperties[HtmlEdit.PropertyNames.Id] = null;
this.mUIItemEdit.SearchProperties[HtmlEdit.PropertyNames.Name] = null;
this.mUIItemEdit.SearchProperties[HtmlEdit.PropertyNames.LabeledBy] = null;
this.mUIItemEdit.SearchProperties[HtmlEdit.PropertyNames.Type] = "SINGLELINE";
this.mUIItemEdit.FilterProperties[HtmlEdit.PropertyNames.Title] = null;
this.mUIItemEdit.FilterProperties[HtmlEdit.PropertyNames.Class] = null;
this.mUIItemEdit.FilterProperties[HtmlEdit.PropertyNames.ControlDefinition] = "type=\"text\" value=\"\"";
this.mUIItemEdit.FilterProperties[HtmlEdit.PropertyNames.TagInstance] = "5";
this.mUIItemEdit.WindowTitles.Add("http://cms.home.psafe.com/");
#endregion
}
return this.mUIItemEdit;
}
In this post, I learned about SearchProperties, but it doesn't look to be an appropriate solution in this case.
Is there any other way to wrap these controls properly?
You might be able to find it if its containing element can be found. You can use the containing element to scope the search. So, find that element's parent, then find an input type=text within it:
var container = new HtmlControl(bw); //where bw is the browser window
HtmlDiv parentDiv = new HtmlDiv(container);
parentDiv.SearchProperties[HtmlDiv.PropertyNames.Id] = "theIdOfYourDiv";
HtmlEdit edt = new HtmlEdit(parentDiv); //the search scope is narrowed down to the div only. This may be enough to find your control with the search property.
edt.SearchProperties[HtmlEdit.PropertyNames.Type] = "SINGLELINE";
You have two options:
Try crowcoder's solution of searching in the parent. The problem with this solution is when you move a control around you're going to be changing code a lot.
Add an Id property to all your controls in the HTML, this will make your Coded UI more robust and responsive to changes in the UI.
I am having trouble type casting and using the right interfaces. I have a function that loops through all text elements with a specific property set. Once a match is found, I want to be able to select this text element or make it active or highlighted or whatever on the map. Code below.
protected override void OnClick(Item item)
{
IMxDocument pDoc = ValidateInterface.GetMxDocument();
IActiveView pLayout = (IActiveView)pDoc.PageLayout;
IGraphicsContainer pGraphicsCont = (IGraphicsContainer)pDoc.PageLayout;
pGraphicsCont.Reset();
IElementProperties _ElemProps = null;
while ((_ElemProps = (IElementProperties)pGraphicsCont.Next()) != null)
{
if (_ElemProps.CustomProperty is IPropertySet2)
{
ITextElement _textElement = (ITextElement)_ElemProps;
IPropertySet2 _propertySet = (IPropertySet2)_ElemProps.CustomProperty;
MessageBox.Show("Before I compare item to string");
if (item.Caption == Convert.ToString(_propertySet.GetProperty(NAME_STRING)))
{
//Problems start here
MessageBox.Show("Inside the IF statement");
IGraphicsContainerSelect _SelectMyElement = null; // = (IGraphicsContainerSelect)pGraphicsCont;
ITextElement _newTextElement = (ITextElement)pGraphicsCont;
IElement TestElement = _newTextElement as IElement;
_SelectMyElement.SelectElement(TestElement);
}
}
}
}
Nothing is being selected though on my map. I'm looping through each graphic element (IGraphicContainer) on the map. Once I find a match, I want to select that Graphic Element. I am trying to utilize IGraphicContainerSelect to do this. It takes an IElement variable type as a parameter, thus why I'm trying to cast it. But again, noting is being selected. This all happens when I click a button.
Any help on this would be greatly appreciated. Thanks in advance.
Try to refresh your map.
I think the better way using pLayout.PartialRefresh or pScreenDisplay.Invalidate methods.
pLayout.PartialRefresh(esriViewDrawPhase.esriViewGraphicSelection,null,pLayout.Extent)
OR
IScreenDisplay pScreenDisplay = pLayout.ScreenDisplay;
pScreenDisplay.Invalidate(null,false,esriViewGraphicSelection);
pScreenDisplay.UpdateWindow();
See help :http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//000100000242000000
I'm looking for the source code to collapse every methods of my active document using the VS2010 Addin.
For the moment I parse the text content of the document trying to match if the line is a method signature. If it is the case, I collapse the method.
TextSelection selection = (TextSelection)_applicationObject.ActiveDocument.Selection;
var editPoint = selection.ActivePoint.CreateEditPoint();
editPoint.MoveToLineAndOffset(1, 1);
while (!editPoint.AtEndOfDocument)
{
editPoint.StartOfLine();
var line = editPoint.GetText(editPoint.LineLength).TrimStart();
if (line.StartsWith("public"))
{
selection.MoveToLineAndOffset(editPoint.Line, 1);
_applicationObject.ExecuteCommand("Edit.ToggleOutliningExpansion");
}
// go to the next line
}
Does anyone could tell me if I'm on the good way or if there is an easiest way ?
Maybe I asked not so well my question. My real goal was to collapse all the code : properties, methods, comments with ///, using; but not the regions.
Here is one solution :
// reduce everything like Ctrl+M+O
_applicationObject.ExecuteCommand("Edit.CollapsetoDefinitions");
// save the cursor position
TextSelection selection = (TextSelection)_applicationObject.ActiveDocument.Selection;
var selectedLine = selection.ActivePoint.Line;
var selectedColumn = selection.ActivePoint.DisplayColumn;
// open the regions
selection.StartOfDocument();
while (selection.FindText("#region", (int)vsFindOptions.vsFindOptionsMatchInHiddenText))
{
// do nothing since FindText automatically expands any found #region
}
// put back the cursor at its original position
selection.MoveToDisplayColumn(selectedLine, selectedColumn);
I hope this could help
I am using below code to inject javascript
HtmlElement head = _wb.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = _wb.Document.CreateElement("script");
mshtml.IHTMLScriptElement element = (mshtml.IHTMLScriptElement)scriptEl.DomElement;
element.text = "function zoom(){document.body.style.zoom='150%';}";
head.AppendChild(scriptEl);
Now can anyone tell me how to remove the added child
I think explicit deleting of an element is not possible (did not check the IHTML interfaces on this).
But this can be done in 2 different ways too:
element.OutherHtml = string.empty; => removes the whole element but does not always work
HtmlElement blankScript = _wb.Document.CreateElement("script");
element = blankScript; => replaces your unwanted script with a blank one