I want to capture a full page screenshot of a webpage that has a sticky header.
Say for example https://www.flipkart.com/ site has the sticky header. I am using Ashot and it took the screenshot like the one below. https://www.flipkart.com/
You can see the header is appearing between the image
It would be really helpful if I could find any ideas on how to achieve
Try with shutterbug https://github.com/assertthat/selenium-shutterbug
There is a lot of options that you can use to crop the page.
First solution
Try with ignore-parts of the screen like 10px from top. You have to play with the tuneup.
Second solution is to edit CSS of the header element, the idea is to change his position to 'relative' so it will not be on top when scrolling.
This is how I did it.
Disable on-top header:
((JavascriptExecutor) driver).executeScript("$('.common-header').css('position', 'relative');");
BufferedImage img = Shutterbug.shootPage(driver, ScrollStrategy.BOTH_DIRECTIONS, 100, true)
.getImage();
Use ShutterBug to Take fullpage screenshot
Shutterbug.shootPage(driver,ScrollStrategy.WHOLE_PAGE,500).withName("FullPageScreenshot").save("/Users/machinename/Desktop/Screen2");
Required jars:
java-semver-0.7.0.jar , selenium-shutterbug-0.9.3.jar
This may help you.
Removing or changing the style property of the sticky header using JAVASCRIPT and taking the scrollable screenshot is not suggested as it is considered as standard way of testing and producing screenprint.
One best way is to use the JS and find the full page height viewport height, sticky header height and scroll and take the screenshot.
You can use the below code.
public void scrollTheStickyHeaderPage(){
/** This function scrolls and takes screenshot **/
JavascriptExecutor js = (JavascriptExecutor) driver;
int fullPageHeight = Integer.parseInt(js.executeScript
("return document.documentElement.ScrollHeight").toString());
int viewportHeight = Integer.parseInt(js.executeScript("return Math.max
(document.documentElement.clientHeight, window.innerHeight || 0)").toString());
int headerHeight = Integer.parseInt(js.executeScript("return Math.max
(document.getElementsByTagName('/**element**/')[0].clientHeight,
document.getElementsByTagName('/**element**/')[0].offsetHeight,
document.getElementsByTagName('/**element**/')[0].scrollHeight || 0)").toString());
int numofScrolls = (fullPageHeight/viewportHeight);
/** call your screenshot function **/
for(int i=1; i<=numofScrolls; i++){
js.executeScript("window.scrollBy(0,"+(viewportHeight-headerHeight)+")");
/** call your screenshot function **/
}
}
I have solved this issue by adding the below-mentioned CSS code in the inspect editor to the header sticky element. You can see the result on this page https://icrmsoftware.com/project/corporate-business-consulting-business-html-template
margin-top: -200px !important
Related
I have a div element that I want to scroll down inside it with selenium.
I want to scroll specific pixels.
What is the easiest way to do it?
I searched on web but didn't find fine explanation.
You can use this method:
public void scrollOnElement(String cssSelector){
JavascriptExecutor js = (JavascriptExecutor)driver;
String script = String.format("document.querySelector('%s').scrollTop= 450",cssSelector);
js.executeScript(script);
}
The css parameter here is the css selector locating the div element you want to scroll inside.
I use 450 pixels scrolling here however you can use any parameter instead.
I'm trying to take multiple screenshots in java selenium webdriver . Taking a site such as mashable.com , there is a static header at the top. When I take my first screenshot there is no problem but as I scroll down to take a screenshot, there is a header on top which blocks some content.
Now, I don't wish to have the header on top. Manually, I played around with the css of the site in chrome. I found that by identifying the id and setting the position from position from fixed to null , I get the header removed. Is it possible to have a general way to identify these headers (only on the top) and modify their css property using javascript ?
You can try this:
$('*').filter(function() {
if ($(this).css('position') === 'fixed'){
$(this).css('position', 'relative');
}
});
I have searched all the forums but I didn't get a correct answer for my issue. My web page to test has a link hidden below, and I am trying to find it manually by searching for it with xpath or the ID attribute of the element, but I am not able to find it when I am running the web driver script. Even when it is not giving any error on that element, I am getting an error on next command/line.
I found below code from the forums, which is scrolling whole page. I don't want this, I want to scroll down vertically in a specific div area as in screen shot.
JavascriptExecutor jsx = (JavascriptExecutor)driver;
jsx.executeScript("ctl00_Menu1_scrollDiv.scrollBy(0,250)", "");
div id for this is "ctl00_Menu1_scrollDiv"
Element id: ctl00_Menu1_DlMenu_ctl09_LnkMenuname
Please help me on this issue. Thanks in advance.
Help will be appreciated.
This is umendra tomar , I have found very simple solution for this, please use the below code for scroll a specific div in html using selenium .
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("document.getElementById('scrollCustom').scrollTop= 450");
scrollCustom = this is the ID of your div which you want to scroll.
document.getElementById = this is use in javascript to locate a webelement.
Don't worry we can use this in java using javascriptExecutor
Check if this works for you.
var s = $('#ctl00_Menu1_scrollDiv').scrollTop();
This will give the current value of the scroll in the div.Use this only if you want to scroll inside a div to a certain point dynamically. Otherwise you can hardcode the scrollTop value inside animate()
Using the current value of your scroll you can parameterize the given below scrollTop parameter
$("#ctl00_Menu1_scrollDiv").animate({ scrollTop: "100px" }); // Here 100 px is just an example
I had used this to scroll a large div programmatically in my webdriver framework. Also, this will work if your AUT has jQuery loaded in the browser.
In Java:
JavascriptExecutor js;
js = (JavascriptExecutor) driver;
js.executeScript("$(\"#ctl00_Menu1_scrollDiv\").animate({ scrollTop: \"100px\" })");
First you should not just reference an element by the id. You should set scrollTop to scroll it to a position.
document.getElementById("ctl00_Menu1_scrollDiv").scrollTop(250);
Non-JQuery solution based on this post.
((JavascriptExecutor) driver).executeScript(
"arguments[0].scrollTop=arguments[1].offsetTop",
divWithScrollbarElement,
elementToScrollTo);
where divWithScrollbarElement is the div element which you are looking to scroll, and elementToScrollTo is the child element which you want to make viewable (which in my case was actually the parent of the element which I was initially trying to view). If elementToScrollTo is not actually in the DOM yet, you may need to use the script once to scroll down as far as possible, and then again once more elements have loaded.
I've been working at this for some time now. I'm using Selenium and WebDriver version 2.33 (with all browsers). I'm using Java, which should be arbitrary. What I'm doing is simply find an element and hover over it, which I have done in earlier code. But for some reason, I can't get this one to work. I'm trying to get an element with this xpath, obtained by right-clicking the element in the HTML in Chrome and clicking "copy xpath":
//*[#id="highcharts-10"]/svg/g[7]/g/rect[1]
This is how I'm trying to get the element (due to "highcharts-10" dynamically changing):
//*[starts-with(#id, 'highcharts')]/svg/g[7]/g/rect[" + barOption + "]
barOption is inputting correctly (there are a bunch of bars that I'm trying to go through)
Here is my Java code:
WebDriverWait wait = new WebDriverWait(getWebDriver(), 5);
WebElement element;
WebDriver driver = getWebDriver();
By by = By.xpath("//*[starts-with(#id, 'highcharts')]/svg/g[7]/g/rect[" + barOption + "]");
Actions action = new Actions(driver);
WebElement elem = wait.until(ExpectedConditions.visibilityOfElementLocated(by));
action.moveToElement(elem);
action.perform();
What am I doing incorrect here? I've tried using switchTo() statements, but there are no iframes that I can correctly switch to. Here is a picture the HTML because I can't get my hands on the actual text:
UPDATED HTML LINK:
http://i1250.photobucket.com/albums/hh527/dr4g1116/Capture_zps6e2bc1b9.png
Anyone have any suggestions for me? Please let me know what I'm doing wrong!
Thanks!!
Try as CSS Selectors :
By by = By.css('div[id^="highcharts"] g[class^="highcharts"] > g > rec')
g.class_name I used,as that <g> tags class name is not visible. Replace that class name with the proper class name.
I just wanted to give a slight update on this. It seems selenium can't see past the SVG tags, so with that being said, I need to find a method to see around them...I will report back if I'm able to find out how.
Thanks all!
From your discussion with Amey i deduced that you have only one highchart. so try directly searching for element "highcharts-tracker" using classname i.e By.ClassName("highcharts-tracker") and then hover on this element itself. This would exactly do what you want to achieve.
Sorry just seeing your comment on my earlier answer.
You can get the values for each bar in barchart by following way:
var barValues = new List<string>();
var actions = new Actions(webDriver); //webDriver is instance of selenium WebDriver.
var chartSeriesGroup = webDriver.FindElement(By.ClassName("highcharts-series-group"));
var chartSeries = chartSeriesGroup.FindElement(By.ClassName("highcharts-series"));
var rectTags = chartSeries.FindElements(By.TagName("rect")); //To get all bars in barchart.
foreach (var rect in rectTags)
{
actions.MoveToElement(rect).Perform(); //Hover mouse on bar.
var trendMarkers = webDriver.FindElement(By.ClassName("highcharts-tooltip"));
barValues.Add(trendMarkers.Text); //Storing tooltip value of bar for later use.
}
I am using same method in my current project for getting values of bars in bar chart. Hope this will help you.
Note : If tooltip for bar shows other information e.g.name etc along with value then you need to write logic for extracting the value part from the complete information stored in barValues.
I have an webpage that displays a java applet. The applet is resized if the window is resized using JavaScript which works fine.
The width and height of the applet is set to 100%. When the applet is loading, an image is displayed
image = "preloader.gif"
Using IE 6/7 everything works fine. But in Firefox, the applet has a height of approximately 200 pixels. The width is correct at 100%. Therefore, the preloader image is cut in half. After the applet has loaded and the javascript resizes the page, width and height are set correctly.
If I change the HTML code and use fixed sizes for the applet, the object displays correctly during loading, but cannot be resized afterwards.
Is there any solution to this problem?
Thanks,
Daniel
ps I'm using the Object / embed Tag, but the problem is the same if I use the applet tag.
I would advise you to implement a CSS based solution and create the applet with 100% size of the containing div. I use this method, it's simple, solid and cross browser reliable. Is there any reason you can't do this?
Hard to say without looking at the page. One possibility is the applet loads before the javascript gets run. In which case you could try loading the applet using javascript (instead of coding it directly in the html).
I was getting the same kind of short-and-wide applet in Firefox and Opera.
Now I create the applet dynamically, and this allows me to calculate the size of its containing div depending on the viewport size. This leads me to believe that you would get what you want if you used a containing div with a size specified in points and not as 100%.
The code I use to create the applet
function initJavaView() {
...
var viewportHeight = window.innerHeight ? window.innerHeight :
$(window).height();
var height = viewportHeight - appletArea.offsetTop - 8;
html = '<div style="width:100%;height:' + height + 'px;">'
if (!$.browser.msie /*&& !$.browser.mozilla*/){
html = html + '<object type="application/x-java-applet;version=1.5" ';
} else {
html = html +
'<object ' +
'classid = "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" '+
'codebase = "http://java.sun.com/update/1.5.0/jinstall-1_5-windows-i586.cab#Version=1,5,0,0" ';
}
html = html + ' width="100%" height="100%">' +
...
appletArea.innerHTML = html;
};
The code running at http://books.verg.es/elements_of_ux.html?format=java
I had the same problem, and I can't find an answer, but I got the solution.
You have to embed the applet code in a Javascript function, and fill the innerHtml of the body with it (or wherever you want to use the applet) shortly after the page is loaded. So...
//optional: add styles
function styleApplet(){
document.getElementsByTagName('body')[0].style.overflow = 'hidden';
}
//complementary funcion so applet code is readable
function documentWrite(chars){
buffer +=chars;
}
//funcion to add all code at once. It is compulsory
function executeWrite(){
document.getElementsByTagName('body')[0].innerHTML = buffer;
buffer = '';
}
function writeApplet(){
documentWrite('<applet code="..... </applet>');
documentWrite('..... ');
documentWrite('</applet>');
executeWrite();
}
$(document).ready(function(){
setTimeout('writeApplet()',100);
setTimeout('styleApplet()',100); //optional
}
Any adds to the answer are helpful :-)