Strategy to use Selenium browser testing with Flutter Web apps [duplicate] - selenium

we want to use Appium/Selenium to do automated testing on a Flutter application. Some elements do not have selectors when viewed in Selenium. In Android we just add ids onto every element and they appear in Appium. How do we do this in a flutter environment?

I found an approach with a workaround which then lets you use Selenium reasonably naturally with Flutter Web (although not working with headless browser)
You need to find the offset of window x y coordinates from screen x y coordiantes. I found this idea in another thread
pageCallibrator.html:
<script>
window.coordinates = [];
document.addEventListener('click', function() {
window.coordinates = [event.pageX, event.pageY];
});
</script>
Then in Selenium setup before running tests (Java example)
int windowScreenOffsetX = 0;
int windowScreenOffsetY = 0;
void callibrateXY(WebDriver driver) {
driver.get("http://localhost:8080/pageCallibrator.html"); //TODO adjust host
Dimension size = driver.manage().window().getSize();
int x = size.width / 2;
int y = size.height / 2;
clickMouseAtXY(x, y);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
List<Object> coordinates = (List<Object>) ((JavascriptExecutor) driver).executeScript("return window.coordinates;");
windowScreenOffsetX = x - (int) (long) coordinates.get(0);
windowScreenOffsetY = y - (int) (long) coordinates.get(1);
}
Now in Selenium to press a Flutter button
WebElement continueToBankButtonElement = findElementWithText(driver, "My button text");
clickMouseAtElement(continueToBankButtonElement);
where you define
import org.openqa.selenium.*
Robot robot = new Robot();
Driver driver = new ChromeDriver(options); // TODO handler exceptions and options in a method
WebElement findElementWithText(WebDriver driver, String text) {
return driver.findElement(containsTextLocator(text));
}
By containsTextLocator(String text) {
return By.xpath("//*[contains(text(), '" + text + "')]");
}
void clickMouseAtElement(WebElement element) {
clickMouseAtXY(element.getLocation().getX() + element.getSize().width / 2, element.getLocation().getY() + element.getSize().height / 2);
}
void clickMouseAtXY(int x, int y) {
moveMouse(x, y);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
/**
* #param x
* #param y
*/
protected void moveMouse(int x, int y) {
robot.mouseMove(x + windowScreenOffsetX, y + windowScreenOffsetY); // Offset of page from screen
}

Prior to this morning I knew nothing of Flutter. A few hours later and I can safely say "you don't." While Flutter makes developing an application quick and easy, it removes a lot of the control you have, including the level of customization you're looking for.
There are hits on this on official Flutter message boards dating back a year or two, but there were no answers.
You could attempt locating everything by text? Kluge, difficult or impossible to maintain, but likely your only option at this point.

Related

How do i tell Selenium to wait until report get ready to download

After the selection of date from the date picker,clicking on 'View Report' button and then its take a time to generate the report and then it download the report.. My following code is working without an error but how do i use fluent wait instead of Thread.sleep(20000),(last line in below code). For fluent or explicit wait i ask to wait for what condition? Also wanted to verify whether the file has been downloaded or not with assertion. Any help will be appreciated.
public void generateReport() throws Exception {
clickDatePicker.click();
log.info("Select the Date from datepicker");
Select month = new Select(selectMonth);
month.selectByValue("0");
log.info("Selected the Month from datepicker");
Select year = new Select(selectYear);
year.selectByValue("2020");
log.info("Selected the Year from datepicker");
act.moveToElement(selectDate).click().build().perform();
buttonViewReport.click();
log.info("Finally clicked on Get Report button ");
Thread.sleep(20000);
}
Check the below method, which will make sure the script will wait until the download is started (for max of the minutes specified in the method call)
public void waitUntilDownloadStarted(WebDriver driver, int maxWaitTimeInMinutes) throws InterruptedException {
// Store the current window handle
String mainWindow = driver.getWindowHandle();
// open a new tab
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("window.open()");
// switch to new tab
// Switch to new window opened
for(String winHandle : driver.getWindowHandles()){
driver.switchTo().window(winHandle);
}
// navigate to chrome downloads
driver.get("chrome://downloads");
Instant startTime = Instant.now();
int elapsedTime = (int) Duration.between(startTime, Instant.now()).toMinutes();
// wait until the download is started
while ( (Long)js.executeScript("return document.querySelector('downloads-manager').shadowRoot.querySelectorAll('#downloadsList downloads-item').length") == 0) {
Thread.sleep(1000);
elapsedTime = (int) Duration.between(startTime, Instant.now()).toMinutes();
if (elapsedTime > maxWaitTimeInMinutes) {
break;
}
}
// close the downloads tab2
driver.close();
// switch back to main window
driver.switchTo().window(mainWindow);
}
Tested as below.
waitUntilDownloadStarted(driver, 10);
Does anything appears like that your download has been generated? or inspect any change in HTML. then you can use the following code to wait until change appears.
WebDriverWait wait=new WebDriverWait(driver, 20000);
wait.until(ExpectedConditions.numberOfElementsToBe(locator, number));
where 20000 is time in milliseconds

Selenium - driver.getWindowHandle() - Firefox stops after opening the new window

I'm using driver.getWindowHandle() for switching between windows. This is working fine in Chrome but in Firefox after clicking on the button that opens the new window, the execution doesn't continue, neither stops. How can I resolve it?
Edit :- Code shared in comment -
String parentWindow = driver.getWindowHandle();
driver.findElement(By.id("mybutton")).click();
Set<String> handles = driver.getWindowHandles();
Code:
String parentWindow = driver.getWindowHandle();
driver.findElement(By.id("myButton")).click();
Set<String> handles = driver.getWindowHandles();
for (String windowHandle : handles) {
if (!windowHandle.equals(parentWindow)) {
driver.switchTo().window(windowHandle);
//call methods
}
}
driver.switchTo().window(parentWindow); // cntrl to parent window
With Selenium 2.53.1 using firefox 47.0.1 as the WebDriver in Java: You need to open the separate windows/browsers in it's own driver. I have having the same problem. No matter how many windows or tabs I opened, "driver.getWindowHandles()" would only return one handle so it was impossible to switch between tabs. I found Chrome worked way better for me.
Once I started using Chrome 51.0, I could get all handles. The following code show how to access multiple drivers and multiple tabs within each driver.
// INITIALIZE TWO DRIVERS (THESE REPRESENT SEPARATE CHROME WINDOWS/BROWSERS)
driver1 = new ChromeDriver();
driver2 = new ChromeDriver();
// LOOP TO OPEN AS MANY TABS AS YOU WISH
for(int i = 0; i < TAB_NUMBER; i++) {
driver1.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
// SLEEP FOR SPLIT SECOND TO ALLOW DRIVER TIME TO OPEN TAB
Thread.sleep(100);
// STORE TAB HANDLES IN ARRAY LIST FOR EASY ACCESS
ArrayList tabs1 = new ArrayList<String> (driver1.getWindowHandles());
// REPEAT FOR THE SECOND DRIVER (SECOND CHROME BROWSER WINDOW)
// LOOP TO OPEN AS MANY TABS AS YOU WISH
for(int i = 0; i < TAB_NUMBER; i++) {
driver2.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
// SLEEP FOR SPLIT SECOND TO ALLOW DRIVER TIME TO OPEN TAB
Thread.sleep(100);
// STORE TAB HANDLES IN ARRAY LIST FOR EASY ACCESS
ArrayList tabs2 = new ArrayList<String> (driver2.getWindowHandles());
// NOW PERFORM DESIRED TASKS WITH FIRST BROWSER IN ANY TAB
for(int ii = 0; ii <= TAB_NUMBER; ii++) {
driver2.switchTo().window(tabs2.get(ii));
// LOGIC FOR THAT DRIVER'S CURRENT TAB
}
// PERFORM DESIRED TASKS WITH SECOND BROWSER IN ANY TAB
for(int ii = 0; ii <= TAB_NUMBER; ii++) {
drvier2.switchTo().window(tabs2.get(ii));
// LOGIC FOR THAT DRIVER'S CURRENT TAB
}
Hopefully that gives you a good idea of how to manipulate multiple tabs in multiple browser windows.

Selenium : Handle a window that popups up randomly

We have a feature that collects customer feedback. For this , when the user logs out , a window pops up up randomly - not every time for every customer.
I want to handle this in my automation code.
Currently, at the log out, I'm expecting a window and switching to it and that code is failing when the popup window doesn't show up.
What's the best way to handle this .
This is what I have so far ...
public static void waitForNumberOfWindowsToEqual(final int numberOfWindows) {
ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return (driver.getWindowHandles().size() == numberOfWindows);
}
};
WebDriverWait wait = new WebDriverWait(driver, BrowserFactory.explicitWait);
wait.until(expectation);
}
I would handle the absence of popup window with a try/catch. Here is an example:
try {
WebDriverWait winwait = new WebDriverWait(driver, 3);
String mainWindow = driver.getWindowHandle();
// wait for 2 windows and get the handles
Set<String> handles = winwait.until((WebDriver drv) -> {
Set<String> items = drv.getWindowHandles();
return items.size() == 2 ? items : null;
});
// set the context on the last opened window
handles.remove(mainWindow);
driver.switchTo().window(handles.iterator().next());
// close the window
driver.close();
// set the context back to the main window
driver.switchTo().window(mainWindow);
} catch (TimeoutException ex) {
System.out.println("No window present within 3 seconds");
}
If possible, the ideal thing to do would be to have a look through the source to work out whether the popup window will appear, however if this isn't achievable you could take the following approach:
// Get the number of windows open before clicking the log out button.
int numberOfWindowsBeforeLogOut = driver.getWindowHandles().size();
// Click the log out button.
logOutButton.click();
// Check how many windows are open after clicking the log out button.
int numberOfWindowsAfterLogOut = driver.getWindowHandles().size();
// Now compare the number of windows before and after clicking the log out
// button in a condition statement.
if (numberOfWindowsBeforeLogOut < numberOfWindowsAfterLogOut) {
// If there is a new window available, switch to it.
driver.switchTo().window(titleOrWindowHandle);
}
In case you don't get the required window, the code will throw a TimeoutException. So, put wait.until(expectation) inside a try block and catch the exception. In code,
try {
wait.until(expectation);
} catch (TimeoutException ex) {
System.out.println("Nowindow This Time");
}

Get the on-screen location of web page with Selenium WebDriver

Is there a way to get the on-screen coordinates of HTML window (page body) with Selenium WebDriver?
Seen this a few times and haven't found an elegant solution from WebDriver yet (they have a param that looks to support in in their ILocatable settings but the method is not implemented yet).
What I do is use UIAutomation to get the windows AutomationElement and use a treewalker to find the actual object of the window - downside is I noticed the browsers occasionally update what their window is so the conditionals have to change every once in awhile to accommodate.
Here is some example code (I removed some company code here so it's more elegant on my end but this should work for C#)
public static Rectangle GetAbsCoordinates(this IWebElement element)
{
var driver = GetDriver(element);
var handle = GetIntPtrHandle(driver);
var ae = AutomationElement.FromHandle(handle);
AutomationElement doc = null;
var caps = ((RemoteWebDriver) driver).Capabilities;
var browserName = caps.BrowserName;
switch (browserName)
{
case "safari":
var conditions = (new AndCondition(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Pane),
new PropertyCondition(AutomationElement.ClassNameProperty, "SearchableWebView")));
doc = ae.FindFirst(TreeScope.Descendants, conditions);
break;
case "firefox":
doc = ae.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document));
break;
case "chrome":
doc = ae.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Chrome Legacy Window"));
if (doc == null)
{
doc = ae.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Google Chrome"));
if (doc == null)
throw new Exception("unable to find element containing browser window");
doc = doc.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document));
}
break;
case "internet explorer":
doc = ae.FindFirst(TreeScope.Descendants, new AndCondition(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Pane),
new PropertyCondition(AutomationElement.ClassNameProperty, "TabWindowClass")));
break;
}
if (doc == null)
throw new Exception("unable to find element containing browser window");
var iWinLeft = (int) doc.Current.BoundingRectangle.Left;
var iWinTop = (int)doc.Current.BoundingRectangle.Top;
var coords = ((ILocatable) element).Coordinates;
var rect = new Rectangle(iWinLeft + coords.LocationInDom.X, iWinTop + coords.LocationInDom.Y, element.Size.Width, element.Size.Height);
return rect;
}
public static IWebDriver GetDriver(this IWebElement e)
{
return ((IWrapsDriver)e).WrappedDriver;
}
public static IntPtr GetIntPtrHandle(this IWebDriver driver, int timeoutSeconds = Timeout)
{
var end = DateTime.Now.AddSeconds(timeoutSeconds);
while(DateTime.Now < end)
{
// Searching by AutomationElement is a bit faster (can filter by children only)
var ele = AutomationElement.RootElement;
foreach (AutomationElement child in ele.FindAll(TreeScope.Children, Condition.TrueCondition))
{
if (!child.Current.Name.Contains(driver.Title)) continue;
return new IntPtr(child.Current.NativeWindowHandle);;
}
}
return IntPtr.Zero;
}
The posted code by Zechtitus is amazing, I tried it under IE11 and Chrome Version 39.0.2171.95 m and it worked like a charm. Although I had to pass the real object of IWebDriver instead of using WrappedDriver because it doesn't work with Chrome. Just for your info, I have Win 7 ultimate x64 and using Selenium WebDriver 2.44. this is the code that I took it from Zechtitus and modified it:
public static Rectangle GetAbsCoordinates(IWebDriver driver, IWebElement element)
{
var handle = GetIntPtrHandle(driver);
var ae = AutomationElement.FromHandle(handle);
AutomationElement doc = null;
var caps = ((RemoteWebDriver)driver).Capabilities;
var browserName = caps.BrowserName;
switch (browserName)
{
case "safari":
var conditions = (new AndCondition(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Pane),
new PropertyCondition(AutomationElement.ClassNameProperty, "SearchableWebView")));
doc = ae.FindFirst(TreeScope.Descendants, conditions);
break;
case "firefox":
doc = ae.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document));
break;
case "chrome":
doc = ae.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Chrome Legacy Window"));
if (doc == null)
{
doc = ae.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Google Chrome"));
if (doc == null)
throw new Exception("unable to find element containing browser window");
doc = doc.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document));
}
break;
case "internet explorer":
doc = ae.FindFirst(TreeScope.Descendants, new AndCondition(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Pane),
new PropertyCondition(AutomationElement.ClassNameProperty, "TabWindowClass")));
break;
}
if (doc == null)
throw new Exception("unable to find element containing browser window");
var iWinLeft = (int)doc.Current.BoundingRectangle.Left;
var iWinTop = (int)doc.Current.BoundingRectangle.Top;
var coords = ((ILocatable)element).Coordinates;
var rect = new Rectangle(iWinLeft + coords.LocationInDom.X, iWinTop + coords.LocationInDom.Y, element.Size.Width, element.Size.Height);
return rect;
}
public static IntPtr GetIntPtrHandle(this IWebDriver driver, int timeoutSeconds = 20)
{
var end = DateTime.Now.AddSeconds(timeoutSeconds);
while (DateTime.Now < end)
{
// Searching by AutomationElement is a bit faster (can filter by children only)
var ele = AutomationElement.RootElement;
foreach (AutomationElement child in ele.FindAll(TreeScope.Children, Condition.TrueCondition))
{
if (!child.Current.Name.Contains(driver.Title)) continue;
return new IntPtr(child.Current.NativeWindowHandle); ;
}
}
return IntPtr.Zero;
}
and I used it like this:
Rectangle recView = GetAbsCoordinates(MyWebDriverObj, myIWebElementObj);
the correct X, Y are then stored in recView.X and recView.Y
As I said, it's working for me for both IE11 and Chrome.
Good luck
hmmm, I cannot directly comment to the one user asking about chrome so I will have to add another comment here.
Basically for UIAutomation you will want to get your hands on a tool called inspect (comes free in the 8.1 SDK). Older tools like uispy would probably work as well.
Basically you would fire up chrome and then fire up the inspector tool - your going to look at the tree like structure and then navigate down to the document which contains the DOM. Turn on highlighting in the tool to make this easier.
Chrome is quite dynamic it seems in the layout of the tree controls - have had to modify it a few times to accomodate the control I am looking at. If your using a different version than I had - basically find the document window in the tree and take a look at all of the control patterns associated with it - this is what I am passing into the PropertyCondition for how to search for the control. Intellisense should bring you up different things to query for like AutomationElement.NameProperty. It the example I had - I noticed there is a difference between when I run chrome on a winXP machine vs a win8 machine... hence the checking for null.
Like I have said before - this is not elegant and would be awesome if it was inbuilt into Selenium (I imagine they have much better methods for determining the coords of the DOM area)... I think this will also be problematic for people moving to Selenium Grid (like I am looking at doing) - far as I know with using it I don't know if you can shuttle over a bunch of supporting dll to selenium to the remote machine... at least without a lot of hacks.
If it still doesn't work for you - give me a specific idea on the OS, Chrome version and I'll try to take a look and give exact Property match. Probably best though if you fiddle yourself as these things are not static unfortunately.
Yes. Its possible. With little trick. Find below my code to get on
screen top position of web element.
public static long getScrollYPosition() {
WebDriver driver = DriverFactory.getCurrentDriver();
JavascriptExecutor jse = (JavascriptExecutor) driver;
Long scrollYPos = (Long) jse.executeScript("return window.scrollY;");
return scrollYPos;
}
long scrollPosition = getScrollYPosition();
long elemYPositionOnScreen = (long) elem.getLocation().getY() - scrollPosition;
you can try in this way:
WebDriver driver=new FirefoxDriver();
driver.get("http://www.google.com");
JavascriptExecutor js=(JavascriptExecutor) driver;
Double i= (Double) js.executeScript("var element = document.getElementById('hplogo');var position = element.getBoundingClientRect();return position.left");
System.out.print(i);
I took a quick look at chrome and you may have better luck with the following.
doc = win.Find.ByConditions(new PropertyCondition(AutomationElement.ClassNameProperty, "Chrome_RenderWidgetHostHWND"));
I think that class name is consistent for chrome... seems to work on older and newer OS's for me - chrome version 34.0.1847.116m. Hope that helps.
This should work once it's supported:
WebElement htmlElement = driver.findElement(By.tagName("html"));
Point viewPortLocation = ((Locatable) htmlElement).getCoordinates().onScreen();
int x = viewPortLocation.getX();
int y = viewPortLocation.getY();
However right now it's throwing the following error:
java.lang.UnsupportedOperationException: Not supported yet.
at org.openqa.selenium.remote.RemoteWebElement$1.onScreen(RemoteWebElement.java:342)
(on org.seleniumhq.selenium:selenium-java:2.46.0)
I needed a this in Robot Framework and I was inspired by Jeyabal's solution, so here is an adaptation that works for me:
${verticalWindow}= Execute Javascript return window.scrollY;
${verticalElement} = Get Vertical Position /xpath
${hasScrolled} = Evaluate (${verticalElement} - ${verticalWindow}) == 0
Nothing from above worked for me. A workaround is to use window.innerHeight and window.innerWidth and work your way up from the the left, bottom corner. This assumes that the browser bottom border is almost 0 (no horizontal scrollbar or thick window decoration).
win_pos = selenium.get_window_position()
win_size = selenium.get_window_size()
win_bottom_y = win_pos['y'] + win_size['height']
# We assume viewport x == window x. For y coordinate we take the bottom
# of the browser and subtract the viewport height
viewport_height = selenium.execute_script('return window.innerHeight')
viewport_width = selenium.execute_script('return window.innerWidth')
viewport_y = win_bottom_y - viewport_height
This is not 100% accurate but it's a good workaround that can be tweaked for your case.
SOOO many factors have to be considered to get the element position relative to the screen. For the longest time I was using the UIAutomation code above, but UIAutomation is unreliable, it crashes or fails to find the browser (for some reason), with EdgeDriver, tabs crash consistently making getting the values via UIAutomation now as a 'fallback'.
That said, when it works, the answer is GOLDEN as to the on-screen coordinates of the HTML page.
However, something that always works is using javascript. So we calculate that first, then also attempt to call UIAutomation. If UIAutomation fails, we use this code's answer. If UIAutomation works, we use the UIAutomation values.
// use javascript to get our html document location, but it's off by 2 pixels compared to uiautomation. uiautomation, however, failed so often that is was unreliable
int outerHeight = Int32.Parse(BrowserHelper.ExecuteJavascript(browser, "return window.outerHeight"));
int innerHeight = Int32.Parse(BrowserHelper.ExecuteJavascript(browser, "return window.innerHeight"));
int outerWidth = Int32.Parse(BrowserHelper.ExecuteJavascript(browser, "return window.outerWidth"));
int innerWidth = Int32.Parse(BrowserHelper.ExecuteJavascript(browser, "return window.innerWidth"));
int browserNavHeight = outerHeight - innerHeight;
int browserNavWidth = outerWidth - innerWidth;
iWinLeft = browserNavWidth + 2;
iWinTop = browserNavHeight + 2;
`
Try this, I hope it will help you :
Rectangle rec = new Rectangle(element.getLocation(), element.getSize());

How can I programmatically create a screen shot of a given Web site?

I want to be able to create a screen shot of a given Web site, but the Web site may be larger than can be viewed on the screen. Is there a way I can do this?
Goal is to do this with .NET in C# in a WinForms application.
There are a few tools.
The thing is, you need to render it in some given program, and take a snapshot of it.
I don't know about .NET but here are some tools to look at.
KHTML2PNG
imagegrabwindow() (Windows PHP Only)
Create screenshots of a web page using Python and QtWebKit
Website Thumbnails Service
Taking automated webpage screenshots with embedded Mozilla
I just found out about the website browsershots.org which generates screenshots for a whole bunch of different browsers. To a certain degree you can even specify the resolution.
I wrote a program in VB.NET that did what you specified, except for the screen size issue.
I embedded a web control(look at the very bottom of all controls) onto my form, and tweaked it's settings(Hide scroll). I used a timer to wait on dynamic content, and then I used "copyFromScreen" to get the image.
My program had dynamic dimensions(settable via command line). I found that if I made my program larger than the screen, the image would just return black pixels for the off screen area. I did not research farther since my job was complete at that time.
Hope that gives you a good start. Sorry for any wrong wordings. I log onto windows to develop only once every couple of months.
Doing at as a screen shot is likely to get ugly. It's easy enough to capture the entire content of the page with wget, but the image means capturing the rendering.
Here's some tools that purport to do it.
You can render it on WebBrowser control and then take snapshot if page size bigger than screen size you have to scroll control take one or more snapshots and then merge all pictures :)
This is the code for creating screenshot programatically:
using System.Drawing.Imaging;
int screenWidth = Screen.GetBounds(new Point(0, 0)).Width;
int screenHeight = Screen.GetBounds(new Point(0, 0)).Height;
Bitmap bmpScreenShot = new Bitmap(screenWidth, screenHeight);
Graphics gfx = Graphics.FromImage((Image)bmpScreenShot);
gfx.CopyFromScreen(0, 0, 0, 0, new Size(screenWidth, screenHeight));
bmpScreenShot.Save("test.jpg", ImageFormat.Jpeg);
Java ScreenShots of WebSite
Combine Screens together for Final Entire WebPage Screenshot.
public static void main(String[] args) throws FileNotFoundException, IOException {
System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe");
ChromeDriver browser = new ChromeDriver();
WebDriver driver = browser;
driver.get("https://news.google.co.in/");
driver.manage().timeouts().implicitlyWait(500, TimeUnit.SECONDS);
JavascriptExecutor jse = (JavascriptExecutor) driver;
Long clientHeight = (Long) jse.executeScript("return document.documentElement.clientHeight");
Long scrollHeight = (Long) jse.executeScript("return document.documentElement.scrollHeight");
int screens = 0, xAxis = 0, yAxis = clientHeight.intValue();
String screenNames = "D:\\Screenshots\\Yash";
for (screens = 0; ; screens++) {
if (scrollHeight.intValue() - xAxis < clientHeight) {
File crop = new File(screenNames + screens+".jpg");
FileUtils.copyFile(browser.getScreenshotAs(OutputType.FILE), crop);
BufferedImage image = ImageIO.read(new FileInputStream(crop));
int y_Axixs = scrollHeight.intValue() - xAxis;
BufferedImage croppedImage = image.getSubimage(0, image.getHeight()-y_Axixs, image.getWidth(), y_Axixs);
ImageIO.write(croppedImage, "jpg", crop);
break;
}
FileUtils.copyFile(browser.getScreenshotAs(OutputType.FILE), new File(screenNames + screens+".jpg"));
jse.executeScript("window.scrollBy("+ xAxis +", "+yAxis+")");
jse.executeScript("var elems = window.document.getElementsByTagName('*');"
+ " for(i = 0; i < elems.length; i++) { "
+ " var elemStyle = window.getComputedStyle(elems[i], null);"
+ " if(elemStyle.getPropertyValue('position') == 'fixed' && elems[i].innerHTML.length != 0 ){"
+ " elems[i].parentNode.removeChild(elems[i]); "
+ "}}"); // Sticky Content Removes
xAxis += yAxis;
}
driver.quit();
}