I am new to PuppeteerSharp and I have searched already on the internet for several hours and also the documentation, but I don't seem to find a solution to my problem.
Now, I have a table with some rows on my webpage (see attached picture). I need to find the row that has some text in one of the columns, and click the button left to it (the black one with an arrow).
I have got my button (at least the td) with JQuery in Firefox Dev tools like this:
$("td: Contains('41818397111')").parent().find("td[id = 'InvoiceDetails']")"
But I do not know how to use this information in PuppeteerSharp
I have tried:
ElementHandle element = await page.QuerySelectorAsync("td:Contains('41818397111')");
ElementHandle hanlde = await page.EvaluateFunctionAsync<ElementHandle>("e=> e.parent().find(\"td[id=['InvoiceDetails']\")", element);
await page.ClickAsync($("td: Contains('41818397111')").parent().find("td[id = 'InvoiceDetails']")")
but neither one works. I think I am missing some information.
Thank you
So, after many tries and a lot of searched, I ended up switching to Selenium, which seems to have better documentation and a lot of examples here.
This is the code, that worked for me:
string locator1 = "td:Contains(\'41818397111\')";
string locator2 = "td[id = \'InvoiceDetails\']";
IWebElement webElement = driver.FindElement(Selenium.WebDriver.Extensions.By.JQuerySelector(locator1).Parent().Find(locator2));
webElement.Click();
Related
I wrote in Python a script which uses Selenium to auto-complete a form. It works with no issues.
I am very new to C# but I thought I would try and port it over so I can build a Windows executable to share it with a couple of non tech-savvy family members.
However, when I try what appears to be the same code, I get a timeout in C#.
As an example, I am trying to click a radio button:
HTML of radio button:
<input data-v-7af3e24c="" type="radio" id="condition-2" name="condition" class="govuk-radios__input" value="false">
Python (this works):
WebDriverWait(driver, max_wait).until(EC.presence_of_element_located(
(By.CSS_SELECTOR, '[id$=condition-2]'))).click()
However, when I try what I think is the same request in C#:
int elementLoadTime = 5; // Max 5 seconds for element to load
var wait = new WebDriverWait(driver, new TimeSpan(0, 0, elementLoadTime));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.CssSelector("[id$=condition-2]"))).Click();
This produces:
Exception thrown: 'OpenQA.Selenium.WebDriverTimeoutException' in WebDriver.dll
The strange thing is, I am able to select the element in C# using the full XPath, so the element is clearly loading, and it strongly suggests the problem is with my CSS selector query.
// This works
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.XPath("/html/body/div[1]/div[2]/main/div/div/form/fieldset/div[2]/div/div/div[2]/label"))).Click();
However, obviously that is a very brittle way of writing the code which will break the moment the site changes slightly.
I have also tried "[id$='condition-2']" and "[id$=\"condition-2\"]", to no avail.
Can anyone shed any light on what I am doing wrong?
Instead of using:
By.CssSelector("[id$=condition-2]")
Just use:
By.Id("condition-2")
If you want to use Xpath instead, do two things. First, forget that there's an option in your browser to 'Copy Xpath' - just purge it from your mind. Second, use this Xpath instead:
By.Xpath("//input[#id=\"condition-2\"]")
From what I understand, the default action of when the Webdriver finds an element is to scroll such that the element is as far up the top of the page as possible. This is an issue because the website I'm working on has a header so every time I try to click on a button, it will instead click on the header. Thus, I want to change the scroll setting so that the element will be at the bottom of the page.
From reading this I was able to find what I wanted to set, however, I'm unable to set the DesiredCapabilites or ChromeOptions when I initialise the ChromeDriver. Could some provide code/steps to do this please?
You can use something like this
var chromeOptions = new ChromeOptions();
chromeOptions.AddUserProfilePreference("intl.accept_languages", "en");
chromeOptions.AddUserProfilePreference("disable-popup-blocking", "true");
var driver = new ChromeDriver(chromeOptions);
Edit-2
If the option you want to set doesn't work for you then try using actions
var elem = driver.FindElements(By.Id("your element"));
Actions action = new Actions(driver);
action.MoveToElement(elem).Click(elem).Perform();//move to list element that needs to be hovered
Edit-3
If the above also doesn't work then your next option is to use Javascript
var elem = driver.FindElements(By.Id("your element"));
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
var success = js.ExecuteScript("arguments[0].click(); return true", elem);
As far as I know you can't change everything through addarguments.
There is a list of what you can do in the Github page. but I have a better solution. you can make your own default settings and save it as a chrome profile. for example I didn't find anything to change homepage with code but this works fine for almost evwerything.
you can use this code :
options.AddArguments( #"user-data -dir=C:\Users\kian\AppData\Local\Google\Chrome\User Data");
options.AddArgument("--profile-directory=Default");
make sure you write the right path and right profile name.
to check the profile name you can go to properties.
properties
you will see the profile name.
there is a good guide for what else u can do in link.
I'm sorry if this question has allready been answered , but I litterally spent more than two weeks searching the Internet for a solution to my issue.
Now , I definitly do not perform the best google searches , and it might seem that my question has several effective answers on the Internet. but I really tried every single solution that I found , without any positive results.
What i'm trying to do is simple , and I did it successfully on many websites :
Navigating to a website using WebBrowser (1).
Waiting for everything to load properly (document completed event).
Download the page using DocumentText property (1).
(1) : I also use WebClient from time to time.
And there it is , I get the html page , and I can exploit it anyway I like. The issue is with a particular website that I cannot obtain the full content inspite of using all the different solutions that I found. I suspected the fact that this page might need to load several scripts before getting the full content. Yet again, I read that WebBrowser does run all the necessarry scripts before triggering the " completed " event, so , apparently , that's not the issue. The page that i'm inquiring about is : http://www.coolmod#com/tarjetas-graficas-nvidia-pci-express
I tried , after that the WebBrowser loads the entire page , looking for random elements using GetElementByID property and checking if I get a null result. It appears that when I try getting an element that does not belong to the products list , i'm successful. But , whenever I try to get an element that belongs to the list it self , I always get a null. Which means , the list it self does not load. and I really don't know why. By the way , I do not prevent the WebBrowser. Navigate () from delivering multiple responses , I allow it to give as many feedbacks as possible , and still , the product list does not load , even when I pass the cookies. I Even tried copying all the content of the document and pasting it through the clipboard. Here is a simple example of what I try to do :
private void catalogueDownload()
{
System.Windows.Forms.WebBrowser wb = new System.Windows.Forms.WebBrowser();
wb.ScriptErrorsSuppressed = true;
wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(Catalogue_DocumentCompleted);
wb.Navigate("http://www.coolmod.com/tarjetas-graficas-nvidia-pci-express");
}
public void Catalogue_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var wb = sender as System.Windows.Forms.WebBrowser;
string output = wb.DocumentText;
File.WriteAllText("testing.html", output);
}
Thanks for giving up your time to read all this.
System.Windows.Forms.WebBrowser is a bit outdated, If I were you, I would consider using an external library for that, Selenium would be my 1st choice, given it has all the necessary integrations with .NET Framework (and a lot of other languages)
Hi I am new to Selenium Webdriver. I can successfully open a webpage and find elements on it.
In one case I have noted that there is a link on a page that becomes clickable after a while. In Firebug on the Script tab, I can see the code for the javascript that does the timer function.
But using Selenium Webdriver if I issue:
driver.PageSource
I cannot see the source code for the Javascript. Delaying for 30 seconds before requesting the source makes no difference. I have tried finding it with various By options using:
driver.FindElement
and so on, but it isnt there.
How does firebug manage to find and show the Javascript source code? Is there a way that I can coerce Selenium Webdriver to return all code referenced by the page?
Or is there a better approach?
Thanks for any advice!
EDIT---------------------
I tried the following in Firefox:
Dim Driver2 As IWebDriver = New Chrome.ChromeDriver
Driver2.Url = "http://mypage"
Dim js As IJavaScriptExecutor = TryCast(Driver2, IJavaScriptExecutor)
Dim title As String = DirectCast(js.ExecuteScript("return JSON.stringify(window)"), String)
and I got
Permission denied to access property 'toJSON'
I read that this wont work in firefox so I tried in Chrome, and got
Blocked a frame with origin "http://mypage" from accessing a
cross-origin frame
and from there no solutions because according to this its a security restriction, apparently you can't access an with Javascript
I'm starting to think Im a bit out of my depth here.
PageSource probably doesn't return an exact snapshot of the DOM & etc.
You can instead inspect javascript using driver.executeScript() but the burden of analyzing the return object may be discouraging.
Regardless - Here's a contrived example:
Object result = driver.executeScript("return JSON.stringify(window)");
System.out.println(result.toString());
I'm trying to display a Loading Please Wait dialog form using devex controls and I can't seem to do it. (using winforms, c#)
I'm using an older version of devex - not the latest. I can't do
SplashScreenManager.ShowDefaultWaitForm()
I need to do this in code without the designer.
1.
I tried:
SplashScreenManager.ShowForm(typeof(WaitDialogForm));
It looks right when it loads, but then it throws an error:
Unable to cast object of type 'DevExpress.Utils.WaitDialogForm' to type 'DevExpress.XtraSplashForm.SplashFormBase'
I tried:
SplashScreenManager.ShowForm(typeof(WaitForm));
This shows an empty form thats too big with no image and no text
I tried:
WaitDialogForm mWaitDialog = new WaitDialogForm() {Visible = false};
mWaitDialog.Show();
The wait form doesn't look right. There are white spaces instead of the image.
I tried:
WaitDialogForm mWaitDialog = new WaitDialogForm() {Visible = false};
mWaitDialog.ShowDialog();
The code doesn't continue executing.
I saw examples of
SplashScreenManager.ShowForm(typeof(WaitForm1));
I don't know how to do this without designer.
Can somebody please assist? I thought I'm doing something simple, but I can't seem to figure it out!
Probably this help u ;)
using (new DevExpress.Utils.WaitDialogForm("Please wait"))
{
//Do your stuff here
}
I don't know if this is in your 13.2 version but from looking at documentation you should be using ShowWaitForm instead of just ShowForm.
SplashScreenManager ssm = new SplashScreenManager();
ssm.ActiveSplashFormTypeInfo = typeof(WaitForm1);
ssm.ShowWaitForm();
If that does not work then i would just try preparing a working solution in the designer and then extracting the code from the designer.cs file.
Found a specific documentation example here