How to wait for each page before taking screenshot? - c#

I'm trying to have Selenium take a screenshot of the current page in the webdriver. I'd also like to set the browser's dimensions before this occurs so that the screenshot can capture an image of a specific size.
I use this to change the window size:
webDrv.Manage().Window.Size = new Size(w, h);
And this to take the screenshot:
Screenshot ss = ((ITakesScreenshot)webDrv).GetScreenshot();
ss.SaveAsFile(Path.Combine(m_path, m_filename), ScreenshotImageFormat.Png);
The problem is that on some pages, the screenshot will be taken before the browser has finished redrawing the page.
I cannot use the usual methods of checking (such as using JS to get the document.readyState) because the page is already loaded at this point, so any checks like this return true.
This is only a problem on pages that use Javascript to resize elements based on window size. Pages that use CSS don't have this problem.
I can get around this by taking the entire HTML Body element before and comparing it to after the resize is completed:
webDrv.Manage().Window.Size = new Size(w, h);
int oldBodyHash = webDrv.FindElement(By.TagName("body")).Text.GetHashCode(); //get a hash of the current html body
DateTime nextthink = DateTime.Now.AddSeconds(10); //hard time out incase there is no javascript resizing
while (webDrv.FindElement(By.TagName("body")).Text.GetHashCode() == oldBodyHash && DateTime.Now < nextthink) //wait until hash changes or timeout occurs
{
Thread.Sleep(500);
}
Screenshot ss = ((ITakesScreenshot)webDrv).GetScreenshot();
ss.SaveAsFile(Path.Combine(m_path, m_filename), ScreenshotImageFormat.Png);
But then on pages using CSS to control changing elements, there is no change in the HTML Body.
It seems like it is one or the other, but it's not possible to cover for both possibilities?

I have the same question question JeffC, but to directly fix you problem try adding a
browser.refresh()
in between the window resize and the screenshot-taking.

Looks like there is no actual solution to this other than changing the order in which we perform the operations; essentially the solution is to change the browser dimensions far enough ahead of time to ensure that JS resize activities complete before the screenshot is taken.

Related

Forcing a "fromUrl" to read a file in Genexus 16U11

I'm working with Genexus 16U11 in C#: I have a web panel with an image variable, when I click a button it should load in the variable an image from a specific URL, so in the event I have
Event 'Dodestra'
&SpeseFoto.FromURL(&targetPath)
EndEvent
Where targetpath is set previously.
It works the first time, but if I change the image in the url, it continues to load always the same image, I need to delete the cache to make it works. As in this program the image in the url has to change very often, this is a problem.
How can I force a reload of the image with the fromURL method?
EDIT: this in Chrome. In Edge and Firefox it correctly sees the new image. I tried to add this Form.Meta.AddItem("pragma","no-cache") but without success
I found a workaround: I can add a random parm to the url, in this way chrome is forced to check again the url&randomn = Random()
&randomn = Random()
&randomx = &randomN * 10000000000
&nomeRandom = &targetPath+"?random="+&randomx.ToString().Trim()
&SpeseFoto.FromURL(&nomeRandom)
Not a lot elegant, but it works

How to place a photo in a specific location in Indesign document using C#?

I need to place photos on Indesign pages, few on each of 100 pgs. I use Place function and it causes to the photo to be loaded on the cursor, and then I need to click on the location I want it. But I need it to be automatic! I mean, to finish placing the photos on the page, but it waits to the user to click.
This is the code:
Indesign.Page pg = doc.Pages[1];
Indesign.TextFrame frm = pg.TextFrames[1];
string txt = frm.Contents;
if (txt.Contains("ploni"))
{
app.Place("C:\\User\\Directory\\PhotoFile.png");
}
I have noticed that Indesign.Page has another parameter in its Place function that called "InsertionPoint". But I didn't understand what is it.
Yes, finally I created a rect, then position it, and then place the image inside. Like this:
InDesign.Rectangle rct = pg.Rectangles.Add(doc.Layers.FirstItem(), InDesign.idLocationOptions.idUnknown, pg);
rct.GeometricBounds = new[] { yDown, xDown, yUp, xUp };
rct.Place(#"C:\User\image.png");
I know nothing about C#, but in Extendscript InDesign DOM Page object has place() method. http://jongware.mit.edu/idcs6js/pc_Page.html And it doesn't wait any click from a user.
You can place image at top-left corner of a page this way:
app.activeDocument.pages[0].place("c:/temp/image.jpg")
I believe C# uses the the more or less same object model as Extendscript.

How to combine multiple PrintVisual() in 1 print-job?

I have a C# WPF application (.NET 4.6) that needs to print a number of Page objects.
Each Page is setup in the XAML editor to be exactly 1 page of A4 in size and the content is build from a number of label, border and image components placed on the Page.
I added a method to my Page class that adds some dynamic data at run-time to the Page and then prints it using PrintVisual().
In fact: Its a loop that fills a Page object with the dynamic content and then calls PrintVisual() to print it. For each iteration, some new content is placed in the Page. (See sample code.)
// Print method of the Page object.
public void PrintIt(int totalpages)
{
PrintDialog pDialog = new PrintDialog();
// If not cancelled then print
if (pDialog.ShowDialog() == false) return; // User cancelled. Don't bother
for(int pagenum=1; i<=totalpages; i++)
{
// Omitted several dozen statements that fill/update the content of various
// label components based on the pagenumber.
this.UpdateLayout(); // Required to re-render new page properly before printing.
pDialog.PrintVisual(this, "My PrintJob");
}
}
This works well, expect for the fact that each PrintVisual() creates a separate print-job, which makes it impossible to print double-sided (and when printing to PDF each page ends up in a new file).
I need to tie all pages (PrintVisual() calls) in a single print-job. I'm fairly sure that I need to use a PrintDocument(), but I can't seem to figure out how to construct the required FlowDocument and populate it with my actual prints.
I'm quite new to WPF programming so I'm probably missing something obvious, but as far as I can't tell there isn't any simple way to do this.
Can anyone give me a push in the right direction ?

WebPage Render Position Controller

First question but I really am in a jam.
I have a webpage render which is working perfectly. However, I need to be able to control the initial display position (almost like a href #anchors in HTML) but without any access to the site content.
From as far as i can see i have no access to the scrollBars other than the bool to enable / disable..
Is there anything i can do to even force a scroll down of 20% for example, and then I can create a form to adjust later on.
Any assistance would be HUGELY appreciated although from what I have researched it seems unlikely.
I have the regular windows WebBrowser Render
private System.Windows.Forms.WebBrowser m_webBrowser;
Thanks !
--This is for c# standalone application.. Not WebBased.
Have you tried using jquery?
I personally use the animate method from jquery to scroll to certain elemnts in my webpage.
Example:
$('html, body').animate({scrollTop: $('#the-element-you-want-to-scroll-to).offset().top}, 1000);
PS: For the last parameter you can control the time it will use to scroll to destination, that offering you a nice effect.(in milliseconds)
I managed to resolve it using a strange method..
I basically injected some javascript into the rendered HTML manually.. Then the rest was easy.
i used something like this :
string updatedSource = WebBrowser.DocumentText.Replace("Google", "Foogle");
string extraSource =
"<html><body>Script goes here <br/>" +
"<div><p>BLA BLA BLA</p></div></body></html>";
WebBrowser.DocumentText = extraSource + updatedSource;
WebBrowser.Update();
Maybe it will help someone.

Check if (mobile)browser support background images

I am building a mobile site and the footer has an background.
I want to check if the browser supports css property, background-image, if true display background with specific html, else display a different set of html.
I am using the following :
HttpBrowserCapabilities bc = new HttpBrowserCapabilities();
I can't seem to get a check for backgrounds.
The reason why I want to check for BG-image support is coz I have to switch between 2 sets of html. 1 with html text and bg image, and the other with the text on the image - sliced for each word/link...to give the same effect.
to get information by HttpBrowserCapabilities, you have to use Request.Browser property.
HttpBrowserCapabilities browerCapabilities = Request.Browser;
I think Asp.net will automatically check the type of the browser and render the page accordingly. So if the the browser don't support background images it will not come.
Another idea to solve the issue is getting the browser type by using code, then you can show or hide the background images based on the type.

Categories