Selenium doesn't click on the top-most element - javascript

Consider the following Selenium automation:
Its goal is to go to a financial chart from the website Barchart, click on the custom calendar icon (at the top right corner over the chart), input a custom range in the form that pops up over it, and validated it using the apply button.
driver = webdriver.Chrome()
url = 'https://www.barchart.com/stocks/quotes/AAPL/interactive-chart'
driver.get(url)
driver.find_element_by_css_selector('.calendar-icon').click()
driver.find_element_by_css_selector('option[label="Intraday"]').click()
driver.find_element_by_css_selector('[data-ng-model="selectedAggregation.range.from"]').send_keys('11/01/2019')
driver.find_element_by_css_selector('[data-ng model="selectedAggregation.range.to"]').send_keys('11/01/2019')
driver.find_element_by_css_selector('[data-ng-model="selectedAggregation.range.to"]').send_keys(Keys.ENTER)
driver.find_element_by_css_selector('[data-ng-click="modalConfirm()"]').click()
It works fine for the most part, until I try to validate, which never works. I then realised that sometime this last action would lead me to a promotional page whose link is located exactly beneath the Apply button. Which seems to indicate that selenium 'click through' the form onto the link below.
I have tried other selector for the apply button, which all give the same result.
I also try to use the submit() method from selenium, which returns an error. Lastly, I also try to implement the execute_script method from selenium, but I did not manage to understand what exactly is the javascript call being executed on clicking apply.
Note : this is because i need to get the cookie and xsrf token that is generated by that call, not because i need to collect the actual financial data ( I know that the financial data can be collected using 'https://www.barchart.com/proxies/timeseries/queryminutes.ashx?' + data), where data are the query string parameters.
Any help greatly appreciated.

I had a look for you, the below should accept the changes for you, I've checked this and it works for me.
javascript = 'document.querySelector("body > div.reveal-modal.fade.interactive-chart-modal-aggregation.in > div > div > div > button.bc-button.light-blue").click()'
driver.execute_script(javascript)

Related

Trying to programatically click a button on a web page with cefsharp

I'm using cefsharp and vb.net to put some code together to move to the next page of this site:
https://www.recommendedagencies.com/search#{}
The idea is to read the list of company names on each page and store to a csv file. This part I can do.
The problem I have is that I can't find the name of the 'Next' button - presumably if I had that I could execute some javascript on the browser to press the button.
I've inspected the page in Firefox, but can't see any name I can use - I'm not really familiar enough with html/page design to know why not or how it works.
Could anyone tell me a good method to get button names from a web page? - I've done some searching and even asked a similar question myself before, but I can't find anything which helps, given my patchy knowledge.
Thanks
Inspect the DOM for the 'Next' button.
Look for id's or classes that you can use to identify it.
use document.querySelector() to find the element by the css selector
call the element.click() function to programatically press next
const nextButton = document.querySelector('.sp-pages-nav_next')
nextButton.addEventListener('click', (event) => {
console.log('something clicked next')
})
nextButton.click()
<div class="sp-pages-nav sp-pages-nav_next" data-reactid=".1.3.4.1">Next</div>
In the above snippet on load you can see the code nextButton.click() invokes the console log. You can click the word Next manually to the same effect.
in cefsharp perhaps something like:
browser.ExecuteJavaScriptAsync("(function(){ document.querySelector('.sp-pages-nav_next').click(); })();");
A very similar example can be found here :
https://github.com/cefsharp/CefSharp/wiki/General-Usage#1-how-do-you-call-a-javascript-method-from-net
// When executing multiple statements, group them together in an IIFE
// https://developer.mozilla.org/en-US/docs/Glossary/IIFE
// For Google.com pre-populate the search text box and click the search button
browser.ExecuteJavaScriptAsync("(function(){ document.getElementsByName('q')[0].value = 'CefSharp Was Here!'; document.getElementsByName('btnK')[0].click(); })();");

Selenium, pop up form (Python)

I am trying to fill forms on certain webpages. I am having success with most
pages however certain ones are giving me trouble.
Some pages have a format where the form is not initially visible on the page itself, instead you need to click a button which then opens a (what seems to be JavaScript) pop up within the page which then needs to be filled.
I have looked around and have seen examples which address how to fill forms which get created in a new pop up window and which get created in alert windows. However I can not seem to find any examples which can solve this particular case.
This is the code I have so far.
driver = webdriver.Chrome()
driver.implicitly_wait(10)
mouse = webdriver.ActionChains(driver)
driver.get(url)
driver.maximize_window()
value = 'fill form'
span_xpath = '//span[contains(text(), "' + value + '")]'
span_element = driver.find_element_by_xpath(span_xpath)
mouse.move_to_element(span_element).click().perform()
time.sleep(5)
Everything works till here, the fill form button gets clicked which opens the form in the browser page.
But when the following is execute an error always arises: "no such element: unable to locate element"
n =driver.find_element_by_id('name')
n.send_keys('john smith')
I have tried to locate the element by, name, id, xpath and so on but no matter what try, it can not locate any of the form elements.
I would greatly appreciate any help on this matter.
First switch using driver.switch_to_frame(0) (parent iFrame)
then switch using driver.switch_to_frame(1) (chiled iFrame)
and then find the element.
Note: instead of using index you can identify the frame using id, name, xpath etc. like any other Web Element and pass that element to switch_to_frame as an argument. This gives more consistency.

How to show devexpress popup control inside a user control from client side

I am using devExpress 11.2 and ASP.NET 4.0. Please bear with me for lengthy problem description.
I have created a user control which contains a ASPxPopupControl (ID = "myPopup")
<dx:ASPxPopupControl ID="myPopup" runat="server" ... </dx:ASPxPopupControl>
and other controls. I also implemented a public method ShowPopup() in which it executes the myPopup.ShowOnPageLoad = true in order to show this popup. This user control is then registered and referenced in my ASPX page. I put this user control into a cell of a table within ASPxRoundPanel with ID="myUC"
In this page, I have a ASPxGridView in which I created a custom command button as follows:
<dx:GridViewCommandColumn VisibleIndex="0" Width="30px" Caption="" ButtonType="Image">
<CustomButtons>
<dx:GridViewCommandColumnCustomButton ID="cmd">
<Image Url="~/Images/OK.png" />
</dx:GridViewCommandColumnCustomButton>
</CustomButtons>
</dx:GridViewCommandColumn>
ClientSideEvents is defined as
<ClientSideEvents BeginCallback="OnDevExpressBeginCallback" EndCallback="OnDevExpressEndCallback">
I would like to popup my user control when this image button is clicked. Please note that this ASPxGridView also provide Insert/Editing/Delete function.
There are two ways to deal with this requirement.
1 In order to ensure ASPxGridView handling its built-in commands (Insert and etc) correctly, I need to set EnableCallBacks="True" then I set OnCustomButtonCallback="OnmyASPxGridView_CustomButtonCallback" to handle the clicking event of the image button from code behind. I called myUC.ShowPopup() from code behind and I debugged up to here. However, the popup is not shown. If I set EnableCallBacks="False" then the popup is shown exactly what I expected.
The problem of this approach is not acceptable because the built-in commands do not work properly. So the question is how can I show the popup control within my user control from code behind while EnableCallBacks="True" ?
2 Second approach is to show popup from client side.
I set EnableCallBacks="True" first to ensure my built-in commands work properly. then I defined ClientSideEvents as
<ClientSideEvents BeginCallback="OnDevExpressBeginCallback" EndCallback="OnDevExpressEndCallback" CustomButtonClick="jsfnShowPopUpControl"/>
and removed OnCustomButtonCallback event.
I implemented javascript function jsfnShowPopUpControl like this:
function jsfnShowPopUpControl(s, e) {
// next, find access control inside user control
**var myPopupName = document.getElementById('<%=myUC.FindControl("myPopup").ClientID %>');**
if (myPopupName != null) {
myPopupName.Show();
myPopupName.PerformCallback(e);
}
else {
alert("Data error encountered"); // cannot find popup
return; //
}}
The key part of this approach is to find the devexpress popup control which resides within a user control. Unfortunately that getElementById function could not find the underneath control in my user control and thus popup is not shown either.
Please help and let me know what I did wrong in my two different approaches.
Thanks a lot.
Reference these- Showing a DevExpress AspxPopUpControl when user clicks a button
How to show ASPxPopupControl's window on the client side
To solve this issue, I suggest you use the ASPxClientPopupControl.ShowWindow method.
For this same scanerio as you want to implement what i have done.
Assigned ClientInstanceName property to some unique name on the page
including the user control now you free to access that object anywhere
in the html through javascript.
Let you set the popup's ClientInstanceName to "MainASPxClientPopupControl". Thus, it should be possible to use it on you main page as follows:
MainASPxClientPopupControl.Show();
Reference on this topic: ASPxPopupControl - Cannot get an instance of the popup from a page

pass data from popup gridview to parent page

the explanation given here http://wiki.asp.net/404.aspx?aspxerrorpath=/themes/fan/pages/page.aspx/282/passing-value-from-popup-window-to-parent-form39s-textbox/
is exactly what I want , but Its not giving the output and parent page despite doing exactly as explained ,
can anyone please send sample website with northwind data base ? no need of mdf file ,just a tested demo I will attach Northwind .
The task s simple , In pop up window there is a grid with some databound column and one with button , my task is when buton is clicked it must return text from respective grd row to the parent page'control (any)
Maybe is not working to you because on the sample is hard code the button id, and this logically because on the popup window did not know how the button have been render.
getElementById("ctl00_ContentPlaceHolder1_TextBox2")
So ether correct this id to make it as its appear to your page, ether make the control id on TextBox2 static so is not change, and get it by name.

How do I access changed (via GridDropDownListColumnEditor) values of a Telerik RadGrid server-side?

Details:
I'm basically trying to implement the functionality of the example here (http://demos.telerik.com/aspnet-ajax/grid/examples/dataediting/editondblclick/defaultvb.aspx) on my own site, but instead of using a data source control located in the page markup (like in the example: SessionDataSource), I'm using a dataset that I get from some server code-behind. I am able to successfully get my double-clicked row into edit mode with my dropdowns successfully populated, however when clicking onto another row to update the one in edit mode, no-dice.
I've discovered that apparently the client-side JavaScript function updateItem() does not initiate an AJAX callback like I originally thought, so I've been trying to work my way around that. Currently I'm using my RadAjaxManager to perform an AJAX callback with the row index number like so:
function RowClick(sender,eventArgs)
{
if(editedRow && hasChanges)
{
hasChanges = false;
$find("<%= RAM.ClientID %>").ajaxRequest(editedRow);
}
}
This gets me to my server code. Awesome. But,
Problem: I must be accessing something wrong, because the GridDataItem cell text that I'm trying to obtain for the edited row all has the value " ".
Dim gdi As GridDataItem = FieldOpsScheduler.Items(rowIndex)
Dim d As DateTime = DateTime.Parse(gdi.Item("EndDate").Text) //<--FAIL
I've been scouring the Internet for hours now trying to find how I can pull off what I'm trying to do, but to no avail.
Additional Info: I'm using GridDropDownListColumnEditors on the front-side to do the editing for my table, declared like so:
<telerik:GridDropDownListColumnEditor ID="ddlce_SunAct" runat="server" DropDownStyle-Width="60px"></telerik:GridDropDownListColumnEditor>
So does anybody have any ideas on what I have to do to access the values that have been changed in my RadGrid?? Is the problem that I somehow need to rebind my RadGrid when clicking on a new row? If so how do I do that? Any solutions or ideas would be greatly appreciated. (Also although I'm doing this in VB.NET, feel free to write responses in C# if you wish as I understand that too. :-) ) Thank you in advance.
With manual binding updateItem() should still raised the UpdateCommand server event of the grid, but you will have to update the grid source by hand. Modify the local version of the online demo where you Telerik AJAX controls installation is and go from there.
Dick
http://www.telerik.com/help/aspnet-ajax/grdaccessingcellsandrows.html
If anyone else has the same problem as I did, go to the above link and scroll down to the section titled "Accessing the value of cells in edit mode".

Categories

Resources