Can not take a full page screenshot in Applitools C# - 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.

Related

c# fail to get element in content page with getelementbyid, getelementsbytagname

I have posted the same question but I post it again since I haven't got any answers to that post yet.
I am trying to get some information (such as tagName, id using GetElementsByTagName method or GetElementById method) from a content page in a website using winforms.
as you see the pictures attached, no matter which selection you make (select1, select2, select3 etc) web address stays same. however, contents under those selections are different in content page.
I am trying to access to a tagName(or id) from one of them(not selections but contents under a specific selection).
I have debugged and figured out(or seems like) I can not access to tagName(or id) from any of those contents under a specific selection.
It seems like I can only access tagName(or id) from main page. picture 3 will help better explanation of some terms such as main page, content page.
I tried to explain in detail, if my question seems still not clear, let me know plz.
My code looks like this.
var countGetFile = webBrowser1.Document.GetElementsByTagName("IFRAME");
foreach (HtmlElement l in countGetFile)
{
if (l.GetAttribute("width").Equals("100%"))
{
MessageBox.Show(l.GetAttribute("height").ToString());
MessageBox.Show(l.GetAttribute("outerText").ToString());
}
}
I was not able to grab information under 2 down level of #document from html.
html looks something like
...
<src="..." id="A" ... >
#document
...
<src="..." id="B" ... >
#document
...
<span="C" ...>
...
I could grab span information (third curly brackets) with codes looking like
HtmlWindow frame1 = webBrowser1.Document.GetElementById("A").Document.Window.Frames["A"];
HtmlWindow frame2 = frame1.Document.GetElementById("B").Document.Window.Frames["B"];
foreach (HtmlElement elm in frame2.Document.All)
{
if (elm.GetAttribute("tagName").Equals("C"))
{
// your command
}
}
to use Document.Window.Frames you need a header using "System.Collections";
btw, there is a problem. When I try to access to the information in third curly bracket, I need to do some kinds of work between frame1 and frame2 such as delaying for frame2 to have enough time to be able to access to next level after frame1.
I figured a kind of hack to get it through. Place a messagebox to pop up for short time delay, or place a delay function( not freeze ) with async code looking like,
async Task PutTaskDelay()
{
await Task.Delay(5000);//5 secs
}
I just found a temporary solution for accessing to second level. I will appreciate anyone who knows some ways to solve this problem.

Take screenshot of full page with selenium

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.

Change Background image every visit

I have about 50 background images for my site. What i am looking to do is randomly present the user with a different one for every visit. By this i mean they will surf through the site with the same background image during their visit.
After they close the browser and re-visit or come back and visit later, they then are presented with a new random background image. Don't need to save anything on what their previous background image was, just a random new one for each new visit to the site.
Not sure it this can be done with C#, Javascript, JQuery or CSS.
EDIT: I am using ASP.net 4.0 C# for my web app. Thanks
Don't use cookies as stated in the comments. This will only add extra bandwidth to the header messages sent to the server.
Instead, use local storage in the browser to save what the last image was they used. When a new session is started increment this value, and display the next image.
I've used jStorage on projects and it works fine.
You can save the currently shown image in their browsers storage, and maybe a session ID. Later, you can check if the session ID has changed. If so, then change to a different image.
var image = $.jStorage.get("image", 0);
var session_id = $.jStorage.get("session", "put current session id here");
if(session_id != "current session id")
{
image = (image < 50) ? 0 : image+1;
$.jStorage.set("image",image);
$.jStorage.set("session","current session id");
}
// use image to set background
EDIT:
Don't place this JavaScript in each web page. Instead, place it in a ASP.NET page that responses as a Javascript content type and load it via the page's header. This way page caching on the browser won't affect the script when the session changes.
Keep it in the Session. Pick it at random when it's not already in the session, it will stay the same as long as they're at your site -- and next time they come back, they'll get a new one.
For example (my C# is a little rusty):
public getBackground (HttpSessionState session) {
String bg = (string) session["session.randomBG"];
if (bg == null) {
// pick a random BG & store it.
bg = "pick one";
session["session.randomBG"] = bg;
}
return bg;
}
Hope this helps!
var list = [
"/images01.png",
"/images02.png",
...
];
/*background url*/ = list[Math.floor(Math.random()*list.length];
Sure it is possible. I will use pseudo-code here to show you how it could be done. Surely soon examples in Java will appear.
In the beginning of each page:
StartSession()
If ! SessionVariable[myBackground] then
x=Randomize 50
SessionVariable[myBackground]="image0" + x + ".jpg"
endif
<style>
body {background-image:url(SessionVariable[myBackground];}
</style>
Make sure you use the style tag where appropriate. The SessionVariable[myBackground] is user-created. In PHP it would look like this:
$_SESSION['myBackground']
Best wishes,
Try this function:
/**
* Change background image hourly.
* Name your images with 0.jpg, 1.jpg, ..., 49.jpg.
*/
function getBackground2() {
var expires = 3600000,
numOfImages = 50,
seed = Math.round(Date.now() / expires % numOfImages);
return '/path/to/background/' + seed + '.jpg';
}

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 :).

Emulating click based event on a web page

This link goes to an implementation of the imagination captcha imagination
The authors have themselves requested for people to make algorithms to try its efficiency against AI attacks.
Essentially the first page is asking for a mouse click anywhere on the image... My problem is that my algorithm comes up with the point (x,y) on the image but I want to emulate it real time on this link...
Can some one tell me how can i send the point values on this link and get back the message whether i was successful or not....
Essentially I am asking how can i emulate a mouse click on this link at the points that my algorithm gives using C#...
I am asking this only for studying the features of this captcha and its accuracy.
Thanks a lot
If you are able to execute JavaScript on that page directly, this code will do:
submitClick(document.getElementById("img").value, x, y, "tiled");
Otherwise, hit this url, substituting your own values for id, x, and y:
http://goldbach.cse.psu.edu/s/captcha/captcha_controller.php?id=87170&x=66&y=149&source=tiled
Parse the response - If your coordinates are correct, the response will contain "step 2". If not, the response will contain "step 1" and it will have a <div id="error">.
If you want to use their live site from code, I think you're talking about a screen scrape. I highly recommend looking into the HTML Agility Pack (available via nuget). This is going to allow you to read the DOM into your application and then interact with it however you please.
This could be a dumb answer but if you're trying to emulate a mouse click and find out if it's successful, why not use the Selenium Browser add-in to record your scripts / write' your own.
Then you can have a test suite to try against you're various different captchas.... hope this achieves what you're trying to do....
WebAii over at telerik has this feature. Here is some sample code i used at some point in the past customized for your situation. just put this in a class, left out the class container because it jacks up the formatting
protected static Manager _manager = null;
protected static Manager _manager = null;
protected Browser _main;
protected Find _find;
public WebAiiAutomater()
{
if (_manager != null)
{
foreach (var broswer in _manager.Browsers)
{
broswer.Close();
}
return;
}
var settings = new Settings(BrowserType.InternetExplorer, #"c:\log\") { ClientReadyTimeout = 60 * 1000 };
_manager = new Manager(settings);
_manager.Start();
_manager.LaunchNewBrowser();
_manager.ActiveBrowser.AutoWaitUntilReady = true;
_main = _manager.ActiveBrowser;
_find = _main.Find;
_main.NavigateTo(#"http://goldbach.cse.psu.edu/s/captcha/");
//start looping over your alogrithm trying different x,y coords against ClickImage(x,y
}
public bool ClickImage(int x, int y)
{
//var beginsearch = _find.ById("captcha_img"); //this should get you the image, but you don't need
_manager.Desktop.Mouse.Click(MouseClickType.LeftClick, x, y);
Thread.sleep(1000); //wait for postback - might be handled internally though
var errordiv = _find.ById("error");
return errordiv !=null;
}

Categories