Wait till the GeckoFX Webbrowser has loaded - c#

I want to automate a few tasks on my website with GeckoFX for some testing.
That should happen when I click a button and everything should be automated after that button click.
This includes clicking buttons where the page refreshes so the code has to wait till the page has loaded and that's where my problem is.
If I do it like that:
geckoWebBrowser1.Navigate("http://mywebsite.com");
GeckoInputElement searchText = new GeckoInputElement(geckoWebBrowser1.Document.GetElementsByName("searchbox")[0].DomObject);
searchText.Value = "GeckoFx";
I get an error, so how can I put it that the code after .Navigate waits till the webbrowser has fully loaded the page?

You can use DocumentCompleted Method to perform your automatic operations.
private void geckoWebBrowser1_DocumentCompleted(object sender,EventArgs e)
{
// Here you can add the coding to perform after document loaded
}
For example : First initiate the browser to google page by geckoWebBrowser1.Navigate("https://www.google.com");
After google page loaded you can do the following in document_completed method:
GeckoInputElement search =new GeckoInputElement(geckoWebBrowser2.Document.GetElementsByName("q")[0].DomObject);
GeckoInputElement button = new GeckoInputElement(geckoWebBrowser2.Document.GetElementsByName("btnG")[0].DomObject);
search.focus();
search.Value = "Master Blaster Sachin";
button.Click();
so it will search the value you given automatically after the google page loaded. Like that you can modify the program as per your logic. Hope it helps..

I would go an use a product like Selenium http://seleniumhq.org/. It's free open source web testing which is scriptable.

Related

PuppeteerSharp - Access a background page, that opens in a new tab, as a regular page

I'm having issues with a program that generates reddit apps with refresh tokens from a discord command.
I've managed to get to a point, where I can generate the application, get all the relevant information, head over to https://not-an-aardvark.github.io/reddit-oauth-helper/ and from there generate the token, which opens a reddit confirmation page in a new window.
I've tried accessing it in various ways and have gone through multiple different methods, until I landed on using Target.PageAsync() to get the page.
For some reason, Puppeteer only sees the page as an iFrame and only gives this link when getting the Url property - https://www.redditmedia.com/gtm/jail?cb=8CqR7FcToPI - which doesn't lead to anywhere but seems to be related to the very first iFrame from what I've gathered in the HTML.
I've ran out of ideas on how to access the page to press quite literally one button and would appreciate any ideas or solutions on how to solve this or how to generate the refresh token without the use of an external website.
Another two hours later and I managed to figure out a solution.
Since PuppeteerSharp was unwilling to recognize the page, I just subscribed to Browser.TargetCreated at the correct moment with a handler that, after immediately unsubscribing, will log the most recent target (in this case, a javascript calling window.open()) and take the sender as the Browser, will then try to get the pages into an array and with a bit of code to ensure that it doesn't break itself, I finally managed a solution, I feel kinda dumb after three days and 12+ hours of work.
For anyone who might run into a similar situation, here's the snippet of code that made it finally work:
// Bla bla bla code to crawl or do whatever on the main page.
// Immediately subscribe to the target created event with the event handler
// that will handle the background page once it has
// been triggered by a button, link, etc.
browser.TargetCreated += TargetCreatedEventHandler;
}
static async void TargetCreatedEventHandler(object sender, TargetChangedArgs e)
{
// Unsubscribe from the event to
// make sure there are no duplicate unnecessary calls that might break the code.
browser.TargetCreated -= TargetCreatedEventHandler;
// Since I know the sender is the Browser object,
// I cast it it to another Browser used inside the event handler.
Browser eventBrowser = (Browser) sender;
// Get all the pages from the event browser
// and assume the first page is background one (for now)
Page[] pages = await eventBrowser.PagesAsync();
Page page = pages[0];
int counter = 0;
// Iterate through the pages, check if they're the page you were just on,
// use an int to help you keep track of of indexes.
// If it isn't the page you were on, assign the Page object the page
// with the current counter index from pages.
// (basically make sure it doesn't break itself with the wrong order).
foreach (var item in pages)
{
if (item.Url != "Main Page URL HERE")
{
page = pages[counter];
break;
}
counter++;
}
// Do whatever you need to do on your background page here
}

Click event not working for Firefox but is for chrome

The click event is not firing in firefox but works ok in chrome.
The test fails with the error: "Element not found on page."
Below is the code and HTML for the button I want to click.
Browser.ElementClickById("ctl00_ContentPlaceHolderBody_lvProducts_ctrl0_ctrl1_btnAddProductToCart_input");
and inside the elementclickbyid i have:
driver.FindElement(By.Id(elementID)).Click();
HTML code is:
event
You could try working around with a Javascript click.
// declare JS executor
var executor = (IJavaScriptExecutor)Driver;
// locate the input
var input = Driver.FindElement(By.XPath("//input[#type='submit']"));
// execute JS to click
executor.ExecuteScript("arguments[0].click();", input);
I've seen cases where regular Click(); does not work across browsers -- these cases are rare, but using JS click usually works across multiple browsers when I run into this issue.
driver.findElement(By.xpath("//input[#type='submit']")).click();
i am sure you are trying to use browser class to keep your methods there, but try to use xpath not id. just use this code to click what you need. don't use page object model or anything else. don't save it in your browser class under click method. just in your main code use this code to click. and before to run it make sure that you have only one type submit. if its gonna show to you 2 types then use this code
driver.findElement(By.xpath("//input[#type='submit'][1]")).click();
number 1 says click to first submit if the button which you need second then follow the logic and change the number to 2
driver.findElement(By.xpath("//input[#type='submit'][2]")).click();
for better answer share your code class and also URL where you are trying to click button and also which element you are trying to click

cefSharp Detect when entire page is loaded

I need to be able to detect when an entire page is loaded. The page has JavaScript that executes when you browse to it as well. And I must wait for that to finish loading as it adds HTML Elements to the page.
I have tried the below event. But this is trigger when the main page loads and doesn't care about the javascript.
browser.LoadingStateChanged
So I also tried count these to know when all the frames on a page where loaded. But it still wasn't spot on.
browser.FrameLoadStart += OnFrameLoadStart;
browser.FrameLoadEnd += OnFrameLoadEnd;
Any suggestions
Ended up using javascript to wait for element to display and then continue

How to download source code of website after having emulated a button click?

With WebClient I can download the source code.
WebClient.DownloadString(url);
With WebBrowser I can emulate mouse click, getting the HTML element by Id and invoking it.
WebBrowser.Document.GetElementById("commit").InvokeMember("click");
My question is: How can I mix these to:
Press the button (one time or multiple times, the id remains unchanged).
Download updated source code (after button click).
P.S. As you can guess the button is a "View more" button that loads new elements, and the url stays the same all the time, there is no page 2. That's why I have a problem.
P.S. This looks like my problem, but in my case it's the same page, not a new window
Let me tell you that it makes no sense to use the WebBrowser and WebClient in conjunction like that. The WebBrowser is not an abstraction of the WebClient or anything like that, they are completely different and they are completely separate.
Assuming you want to persue this problem using the WebBrowser, you could download the page source using the WebBrowser component like so:
webBrowser1.Document.GetElementById("commit").InvokeMember("click");
webBrowser1.DocumentCompleted += (o, args) =>
{
string pageSource = webBrowser1.DocumentText;
};

Cancel Requests on link clicked asp.net

I have a home page on a website (ASP.NET 4.0 C#) which loads a lot of data every time it is accessed (basically a dashboard). This can (depending on the user) take a while to load, so I broke each section into update panels and load them separately so that the user can see it loading and not just think it the page has frozen. However this presents new issues because if the user does not want to wait and clicks on the navigation menu (or a link) to a different page, they have to wait until the page has fully loaded before it moves on.
Is there anyway to stop page requests loading the data if another link is clicked and just deal with that link?
Further info - I am using a master page where the navigation menu is located and also ajax update panels on the home page.
function cancelPostBack() {
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (prm.get_isInAsyncPostBack()) {
prm.abortPostBack();
}
}
Attach this function to the onclick event of the navigation item to ensure any pending requests are cancelled before navigation continues.

Categories

Resources