Take screenshot of full page with selenium - c#

I have the code that takes a screenshot after every step, however it is only taking the screenshot of the current view point. I would like it to take the screenshot of the entire page.
I have looked into things like aShot but I don't know how to add it to my project.
Current code:
[AfterStep]
public void AfterStep()
{
Screenshot ss = ((ITakesScreenshot)webDriver).GetScreenshot();
string stepTitle = ScenarioContext.Current.StepContext.StepInfo.Text;
string fileTitle = DateTime.Now.ToString("yyyyMMdd_HHmmss")+ "_" + stepTitle;
string drive = (path + DateTime.Now.ToString("yyyyMMdd_HHmm") + "_" + testTitle);
string screenshotfilename = drive + "\\" + fileTitle + ".Png";
ss.SaveAsFile(screenshotfilename, ScreenshotImageFormat.Png);
}
Edit:
My problem is not to do with the action of taking a screenshot exactly. The issue I am facing is my page extends the height of the browser and therefor when I take a screenshot, it is a screenshot of the view-able page and not the entire page.

Have you tried the following at the start of your test?
webDriver.Manage().Window.Maximize();
e.g. you could include it here:
[Binding]
public class Setup
{
public static IWebDriver Driver = new ChromeDriver();
[BeforeTestRun]
public static void SetUpBrowser()
{
Driver.Manage().Window.Maximize();
}
note: it may have a slightly different syntax to 'BeforeTestRun' in Gherkin

If your browser is on top and you see it on your screen, try using C#'s screenshot feature (that will take a screenshot of the whole screen). Like clicking PrtScn button that will save the whole screen.
Implementations within the webdriver itself (like the code you showed), IMO should take a screenshot only of the webdriver, since you are asking webdriver to take a screenshot of what it handles (the browser window). If you want a full screen, just use some of the implementations used in the link below.
Capture a Screen Shot using C#
Edit: If you want to take a screenshot of the whole page even though it is not visible (and you have to scroll down to see it), it seems it is not possible as shown here:
how to get screenshot of full web page using selenium in java?

You may want to try this feature of selenium:
set_window_size(int(width), int(height))
I just set window size to 4800*2560 and captured whole page at once which I had to scroll down twice on a 27-inch screen.

Related

Selenium webdriver + C#

I tried to ask question and i was asked to be specific so here I'll try to be specific as much as possible.
1)Check that not less than 4 news are displayed into the news section
-Check, that text “© 2019 Belarusian Railway” is displayed at the
bottom of the page
Check, that 5 buttons are present in the top part of the page: “Press
Center”, “Timetable”, “Passenger Services”, “Freight”, “Corporate”
here I tried to use location property with X and Y coordinates but
after I asked question to my mentor he said I won't be able to
determine it with this approach, so I have no idea how to check where
element is located
Type in “Поиск” input 20 random symbols (they should be different
for each execution). I know about sendKeys method but how do I make
my input random for each run
Check, that address in browser changed to the
https://www.rw.by/search/?s=Y&q=
Check, that text “К сожалению, на ваш поисковый запрос ничего не
найдено.” is displayed on a page
Clear entered random value from corresponding input, and enter
"Санкт-Петербург" instead
click the find button. I know how to do this step
Chech, that 15 links to the articles are displayed on the screen. No
idea how to do this
Write into the console text from that links
Here is the code for the tasks i managed to complete
[Test]
public void Test1()
{
var inputField = driver.FindElement(_inputField);
inputField.SendKeys("белорусская железная дорога");
var searchBtn = driver.FindElement(_searchButton);
Thread.Sleep(1000);
searchBtn.Click();
var targetUrl = driver.FindElement(_targetLink);
targetUrl.Click();
Assert.Pass();
}
}

Can not take a full page screenshot in Applitools C#

I'm trying to take a full screen screenshot of my page by using this code:
public void OpenEyesForVisualTesting(string testName) {
this.seleniumDriver.Driver = this.eyes.Open(this.seleniumDriver.Driver, "Zinc", testName);
}
public void CheckScreenForVisualTesting() {
this.eyes.Check("Zinc", Applitools.Selenium.Target.Window().Fully());
}
public void CloseEyes() {
this.eyes.close();
}
but instead I just get a half a page of the screenshot, I tried to contact Applitools but they just told me to replace eyes.checkwindow() to eyes.Check("tag", Target.Window().Fully()); which still didn't work.
If anyone can help me that would be great.
I work for Applitools and sorry for your troubles. Maybe you did not see our replies or they went to your spam folder. You need to set ForceFullPageScreenshot = true and StitchMode = StitchModes.CSS in order to capture a full page screenshot.
The below code example is everything you'd need to do in order to capture a full page image. Also, please make sure your .Net Eyes.Sdk version is >= 2.6.0 and Eyes.Selenium >= 2.5.0.
If you have any further questions or still encountering issues with this please feel free to email me directly. Thanks.
var eyes = new Eyes();
eyes.ApiKey = "your-api-key";
eyes.ForceFullPageScreenshot = true;
eyes.StitchMode = StitchModes.CSS;
eyes.Open(driver, "Zinc", testName, new Size(800, 600)); //last parameter is your viewport size IF testing on a browser. Do not set if testing on a mobile devices.
eyes.CheckWindow("Zinc");
//or new Fluet API method
eyes.Check("Zinc", Applitools.Selenium.Target.Window().Fully();
eyes.Close();
Use extent Reporting library, in that you can take screen shot as well as an interactive report on pass and fail cases.
here is the link how it works:
http://www.softwaretestingmaterial.com/generate-extent-reports/
If you want to take complete page Screenshot/ Particular element with Applitools. You can use lines of code:-
Full Screenshot
eyes.setHideScrollbars(false);
eyes.setStitchMode(StitchMode.CSS);
eyes.setForceFullPageScreenshot(true);
eyes.checkWindow();
Take screenshot for particular element
WebElement Button = driver.findElement(By.xpath("//button[#id='login-btn']"));
eyes.setHideScrollbars(false);
eyes.setStitchMode(StitchMode.CSS);
eyes.open(driver, projectName, testName);
eyes.setMatchLevel(MatchLevel.EXACT);
eyes.checkElement(Button );
(I am from Applitools.)
When setting forcefullpagescreenshoot to true, applitools will try to scroll the HTML element in the page, if the HTML is not the scrollable element then you will need to set it yourself:
eyes.Check(Target.Window().ScrollRootElement(selector))
In Firefox, you can see a scroll tag near elements that are scrollable.

How to simply find coord's of Image B (smaller ) inside of image A (screenshot /big)?

I am trying to make a basic tool which will automatically move the mouse to a menu, and select from a drop-down menu the thing that's been selected.
So, this is the bit, that I'm trying to get my mouse to navigate to, specifically the "saimon" part. I will refer to this screenshot as A
The screenshot of the user's window, is a bigger picture than A. I just want to navigate to A's section within that screen.
Hopefully you understand the objective here.
Anyways, I was trying to do something simple like using an If statement, to see if I would find that icon within the screenshot, and if I did. It would navigate to those coordinates (I could input it manually, by having the user put the menu in a specific location OR grab the coordinates automatically). If it did not match, I would just say an error.
This answer uses OCR to find the location X,Y coordinates of the text 'Saimon'
You download TessNet(2)
Tessnet2 is a .NET 2.0 Open Source OCR assembly using Tesseract engine.
You can implement code similar to this:
using System;
namespace OCRTest
{
using System.Drawing;
using tessnet2;
class Program
{
static void Main(string[] args)
{
try
{
var image = new Bitmap(#"C:\OCRTest\saimon.jpg");
var ocr = new Tesseract();
ocr.SetVariable("tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.,$-/#&=()\"':?"); // If digit only
//#"C:\OCRTest\tessdata" contains the language package, without this the method crash and app breaks
ocr.Init(#"C:\OCRTest\tessdata", "eng", true);
var result = ocr.DoOCR(image, Rectangle.Empty);
foreach (Word word in result){
if(word.contains("aimon")){
Console.WriteLine("" + word.Confidence + " " + word.Text + " " +word.Top+" "+word.Bottom+ " " +word.Left + " " +word.Right);
}
}
Console.ReadLine();
}
catch (Exception exception)
{
}
}
}
}
You should be able to use these coordinates to automate your mouse to click.
To test online with another OCR how OCR works, please provide your screenprint and check their results. OCR is so good these days!

disable IE visibility while using WatiN

I use watin, because I need to open some websites in the background for which the user needs to support Javascript. I don't know if WatiN is the best for this job, but at the moment it takes very long until Internet Explorer gets visible. I need to disable to popping up of Internet Explorer while using WatiN. User doesn't need to see the opening of sites. Is it possible while using WatiN to visit a website without showing it the user or should I use another alternative which supports JS on client side?
My code at the moment;
public static void visitURL()
{
IE iehandler = new IE("http://www.isjavascriptenabled.com");
if (iehandler.ContainsText("Yes"))
Console.WriteLine("js on");
else
Console.WriteLine("js off");
}
The WatIn.Core.IE class has a Visible property, you can initialize the object like that:
new WatiN.Core.IE() { Visible = true }
This way the IE will just blink on the screen when it's created, and then it will get hidden. You can later control the visibility of the IE with the ShowWindow method of WatiN.Core.IE class - I mean you can show it on the screen if you need, or you can hide again.
I use exactly that trick (of hiding IE) for writing UnitTests (using https://github.com/o2platform/FluentSharp_Fork.WatiN) that run in an hidden IE window
For example here is how I create a helper class (with an configurable hidden value)
public IE_TeamMentor(string webRoot, string path_XmlLibraries, Uri siteUri, bool startHidden)
{
this.ie = "Test_IE_TeamMentor".popupWindow(1000,700,startHidden).add_IE();
this.path_XmlLibraries = path_XmlLibraries;
this.webRoot = webRoot;
this.siteUri = siteUri;
}
which is then consumed by this test:
[Test] public void View_Markdown_Article__Edit__Save()
{
var article = tmProxy.editor_Assert() // assert the editor user (or the calls below will fail due to security demands)
.library_New_Article_New() // create new article
.assert_Not_Null();
var ieTeamMentor = this.new_IE_TeamMentor_Hidden();
var ie = ieTeamMentor.ie;
ieTeamMentor.login_Default_Admin_Account("/article/{0}".format(article.Metadata.Id)); // Login as admin and redirect to article page
var original_Content = ie.element("guidanceItem").innerText().assert_Not_Null(); // get reference to current content
ie.assert_Has_Link("Markdown Editor")
.link ("Markdown Editor").click(); // open markdown editor page
ie.wait_For_Element_InnerHtml("Content").assert_Not_Null()
.element ("Content").innerHtml()
.assert_Is(original_Content); // confirm content matches what was on the view page
var new_Content = "This is the new content of this article".add_5_RandomLetters(); // new 'test content'
ie.element("Content").to_Field().value(new_Content); // put new content in markdown editor
ie.button("Save").click(); // save
ie.wait_For_Element_InnerHtml("guidanceItem").assert_Not_Null()
.element ("guidanceItem").innerHtml()
.assert_Is("<P>{0}</P>".format(new_Content)); // confirm that 'test content' was saved ok (and was markdown transformed)
ieTeamMentor.close();
}
Here are a number of posts that might help you to understand how I use it:
https://github.com/TeamMentor/Dev/tree/master/Source_Code/TM_UnitTests/TeamMentor.UnitTests.QA/TeamMentor_QA_IE
http://blog.diniscruz.com/2014/07/how-to-debug-cassini-hosted-website-and.html
http://blog.diniscruz.com/2014/07/using-watin-and-embedded-cassini-to-run.html
http://blog.diniscruz.com/search/label/WatiN

Webbrowser control is not showing Html but shows webpage

I am automating a task using webbrowser control , the site display pages using frames.
My issue is i get to a point , where i can see the webpage loaded properly on the webbrowser control ,but when it gets into the code and i see the html i see nothing.
I have seen other examples here too , but all of those do no return all the browser html.
What i get by using this:
HtmlWindow frame = webBrowser1.Document.Window.Frames[1];
string str = frame.Document.Body.OuterHtml;
Is just :
The main frame tag with attributes like SRC tag etc, is there any way how to handle this?Because as i can see the webpage completely loaded why do i not see the html?AS when i do that on the internet explorer i do see the pages source once loaded why not here?
ADDITIONAL INFO
There are two frames on the page :
i use this to as above:
HtmlWindow frame = webBrowser1.Document.Window.Frames[0];
string str = frame.Document.Body.OuterHtml;
And i get the correct HTMl for the first frame but for the second one i only see:
<FRAMESET frameSpacing=1 border=1 borderColor=#ffffff frameBorder=0 rows=29,*><FRAME title="Edit Search" marginHeight=0 src="http://web2.westlaw.com/result/dctopnavigation.aspx?rs=WLW12.01&ss=CXT&cnt=DOC&fcl=True&cfid=1&method=TNC&service=Search&fn=_top&sskey=CLID_SSSA49266105122&db=AK-CS&fmqv=s&srch=TRUE&origin=Search&vr=2.0&cxt=RL&rlt=CLID_QRYRLT803076105122&query=%22LAND+USE%22&mt=Westlaw&rlti=1&n=1&rp=%2fsearch%2fdefault.wl&rltdb=CLID_DB72585895122&eq=search&scxt=WL&sv=Split" frameBorder=0 name=TopNav marginWidth=0 scrolling=no><FRAME title="Main Document" marginHeight=0 src="http://web2.westlaw.com/result/dccontent.aspx?rs=WLW12.01&ss=CXT&cnt=DOC&fcl=True&cfid=1&method=TNC&service=Search&fn=_top&sskey=CLID_SSSA49266105122&db=AK-CS&fmqv=s&srch=TRUE&origin=Search&vr=2.0&cxt=RL&rlt=CLID_QRYRLT803076105122&query=%22LAND+USE%22&mt=Westlaw&rlti=1&n=1&rp=%2fsearch%2fdefault.wl&rltdb=CLID_DB72585895122&eq=search&scxt=WL&sv=Split" frameBorder=0 borderColor=#ffffff name=content marginWidth=0><NOFRAMES></NOFRAMES></FRAMESET>
UPDATE
The two url of the frames are as follows :
Frame1 whose html i see
http://web2.westlaw.com/nav/NavBar.aspx?RS=WLW12.01&VR=2.0&SV=Split&FN=_top&MT=Westlaw&MST=
Frame2 whose html i do not see:
http://web2.westlaw.com/result/result.aspx?RP=/Search/default.wl&action=Search&CFID=1&DB=AK%2DCS&EQ=search&fmqv=s&Method=TNC&origin=Search&Query=%22LAND+USE%22&RLT=CLID%5FQRYRLT302424536122&RLTDB=CLID%5FDB6558157526122&Service=Search&SRCH=TRUE&SSKey=CLID%5FSSSA648523536122&RS=WLW12.01&VR=2.0&SV=Split&FN=_top&MT=Westlaw&MST=
And the properties of the second frame whose html i do not get are in the picture below:
Thank you
I paid for the solution of the question above and it works 100 %.
What i did was use this function below and it returned me the count to the tag i was seeking which i could not find :S.. Use this to call the function listed below:
FillFrame(webBrowser1.Document.Window.Frames);
private void FillFrame(HtmlWindowCollection hwc)
{
if (hwc == null) return;
foreach (HtmlWindow hw in hwc)
{
HtmlElement getSpanid = hw.Document.GetElementById("mDisplayCiteList_ctl00_mResultCountLabel");
if (getSpanid != null)
{
doccount = getSpanid.InnerText.Replace("Documents", "").Replace("Document", "").Trim();
break;
}
if (hw.Frames.Count > 0) FillFrame(hw.Frames);
}
}
Hope it helps people .
Thank you
For taking html you have to do it that way:
WebClient client = new WebClient();
string html = client.DownloadString(#"http://stackoverflow.com");
That's an example of course, you can change the address.
By the way, you need using System.Net;
This works just fine...gets BODY element with all inner elements:
Somewhere in your Form code:
wb.Url = new Uri("http://stackoverflow.com");
wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wbDocumentCompleted);
And here is wbDocumentCompleted:
void wb1DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var yourBodyHtml = wb.Document.Body.OuterHtml;
}
wb is System.Windows.Forms.WebBrowser
UPDATE:
The same as for the document, I think that your second frame is not loaded at the time you check for it's content...You can try solutions from this link. You will have to wait for your frames to be loaded in order to see its content.
The most likely reason is that frame index 0 has the same domain name as the main/parent page, while the frame index 1 has a different domain name. Am I correct?
This creates a cross-frame security issue, and the WB control just leaves you high and dry and doesn't tell you what on earth went wrong, and just leaves your objects, properties and data empty (will say "No Variables" in the watch window when you try to expand the object).
The only thing you can access in this situation is pretty much the URL and iFrame properties, but nothing inside the iFrame.
Of course, there are ways to overcome teh cross-frame security issues - but they are not built into the WebBrowser control, and they are external solutions, depending on which WB control you are using (as in, .NET version or pre .NET version).
Let me know if I have correctly identified your problem, and if so, if you would like me to tell you about the solution tailored to your setup & instance of the WB control.
UPDATE: I have noticed that you're doing a .getElementByTagName("HTML")(0).outerHTML to get the HTML, all you need to do is call this on the document object, or the .body object and that should do it. MyDoc.Body.innerHTML should get the the content you want. Also, notice that there are additional iFrames inside these documents, in case that is of relevance. Can you give us the main document URL that has these two URL's in it so we / I can replicate what you're doing here? Also, not sure why you are using DomElement but you should just cast it to the native object it wants to be cast to, either a IHTMLDocument2 or the object you see in the watch window, which I think is IHTMLFrameElement (if i recall correctly, but you will know what i mean once you see it). If you are trying to use an XML object, this could be the reason why you aren't able to get the HTML content, change the object declaration and casting if there is one, and give it a go & let us know :). Now I'm curious too :).

Categories