Python back to previous page with remembering the elements - javascript

My script scrapes the page and if there is a new element according to my requirements, it clicks the button, when there is only one element everything is perfect but problem is when it clicks the button, a new page opens. So if there are more than one element, I need to get back to previous page to continue process.
I tried browser.back() for sure, but when it comes back to previous page it doesn't remember the elements and gives this error as I expected: selenium.common.exceptions.StaleElementReferenceException: Message: Element not found in the cache - perhaps the page has changed since it was looked up with the line if len(css(".Total", parent=new, nowait=True)) > 0: which is the first line, I made it to recognise the new elements.
I also tried to open a new tab/window by clicking the button but button doesn't have this feature because it is javascript. Is there a efficent way to solve this issue?

first_window_handler = driver.current_window_handle
driver.find_element_by_css_selector("body").send_keys(Keys.CONTROL + 't')
second_window_handler = driver.window_handles[1]
# from second page
driver.switch_to.window(second_window_handler)
element_from_second = driver.find_element_by_css_selector('something')
# from first page
driver.switch_to.window(first_window_handler)
element_from_first = driver.find_element_by_css_selector('something else')
now you can switch between windows, and the elements will still be interactable

As per exception
selenium.common.exceptions.StaleElementReferenceException: Message: Element not found in the cache - perhaps the page has changed since it was looked up
we came to know that whenever page loads webdriver loosing references to webelements which it holds previously.
So the best thing is always pass locators dynamically on calling predefined keywords/methods in java prospective, so that webdriver looks for that web element at that instance and perform action.
Some times we may receive same exception in looping list of web elements, because in loop due to actions webdriver may loose reference, so in loop also we need to specify locators so that it will not fail. example if i need to click on links, i will give path like this "//a["+i+"]"
Thank You,
Murali

Related

SugarCRM popup window snapshotForm

My company has a customer who needs some somewhat complex asset system of self referencing elements. Think of it like a building that has the walls, made of bricks, it has a heating system with a boiler and pipes and radiators and each of these are divided into components too. Each such component, the building, the wall and it's bricks, are stored separately as instances of the asset module.
When filling out the relationship between these assets, you can use the usual pop-up selector window doodad thing, but as soon as we try searching for anything, the system suddenly starts screaming about navigating away from the page.
Now I've traced down exactly what's going on here, there's a JS function defined in src_files\include\javascript\sugar_3.js called snapshotForm that records what the popup form contains on load and then it compares this recorded value with it's state on-close or navigate away to see if it's ok to just move on or if it should throw a tantrum.
Now I can't see anywhere in the module, either sugar/custom/module/udef_asset or sugar/module/udef_asset where anything would get in the way of this snapshot, so my question is simple:
Where can I update the snapshot in a way that ensures the whole page has loaded first? Does anyone have any alternative ideas?
I've figured out the solution to my problem, it was due to a dependant dropdown in the child Create form.
The dropdown had a blank default value and thus was being snapshotted with that blank value. However, once the Sugar systems got a second glance, they realised "hey, you can't be blank, that's not allowed value considering your dependencies!" and thus changed it.
Therefore, on searching for another record, it threw the confirmation.
To find the error I ran the following in the Chrome js console:
snapshotForm(document.getElementById("form_QuickCreate_udef_asset"))
which showed me what the current snapshot would be and:
editViewSnapshots[document.getElementById("form_QuickCreate_udef_asset").id]
which showed me the original snapshot taken. I spotted the error as being in the somewhat complex string ...s_1_nameasset_statusDraftasset_imagedescriptio... where we find the asset_status = Draft bit. In the original, it didn't have the Draft there.
To fix, I could have added blank as an option to the default dependant options, but instead I set the value as default away from blank so that it would load in with the appropriate value.

Why doesn't the value of info.frameUrl remain constant when clicking the same element of a page?

This question is based on a misconception, please see this question instead.
Subject
I am trying to create some context menu options via a Google Chrome extension that allow you to modify the contents of editable fields on certain web pages. My extension works perfectly on StackOverflow, where the DOM is nice and simple, but Youtube has been giving me trouble for some time now.
Problem
Many of the editable fields on Youtube are hidden in Iframes, so if I try to access document.activeElementfrom the top frame, I get the Iframe itself.
I am trying to get around this by injecting chrome.runtime.onMessage() listeners into every page.
Then, I can presumably compare the value returned by info.frameURL in the chrome.contextMenus.onClicked() event listener in the event page, with window.location.href in the content scripts to see if the message is addressing the correct frame or not. (See this question)
The problem is that the value returned by info.frameURL does not seem to be consistent.
For example, if you go to the home page and use the main search box as the test element, sometimes the value is simply, www.youtube.com...., but other times it is plus.google.com..... or apis.google.com..... or accounts.google.com... and I am not sure why this is.
Can someone explain why the value returned by the info.frameUrl would not remain constant each time you click the same frame?

Setting focus with Selenium WebDriver

I have a Selenium WebDriver test where I enter some text into a text input box
var input_Note = Driver.Instance.FindElement(By.Id("note"));
input_Note.SendKeys("test");
I then attempt to click on the Save button, but it does not work. I was previously using Coded UI where there is a SetFocus element that points the focus towards whichever element you are targeting. Is there something similar in Selenium?
var button_Save = Driver.Instance.FindElement(By.Id("save"));
button_Save.Submit();
Sometimes depending on how the page is loaded it will exist and then not exist and then exist again. I have found that waiting on the element is a good idea and sometimes will put two waits back to back for the specific element that this will solve this issue(I would say a programming fix for a double wait would be desired...screen flashing too much at that point). This really depends on the load pattern of your application though.
WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(10));
wait.Until (d=> Driver.Instance.FindElement(By.Id("save")));
I would also utilize the .click if it is a button. In general it should be a submit action, but it doesn't always have to be a submit action. There may also be situations where you might need to gain the focus...which shouldn't be programmed that way, but in case it is you can utilize the Actions class and move the mouse to the element and then perform a click action on the element.
//C# example:
OpenQA.Selenium.UI.Interactions.Actions actions = new OpenQA.Selenium.UI.Interactions.Actions();
actions.MoveToElement([Instance of Web Element goes here]).Perform();
actions.Click([Instance of Web Element goes here]).Perform();
In general you could just use the actions.Click, but figured I would give both.
One of the above should work just fine. If it does not work please provide a specific error message you get with Selenium and the specific html structure of the page being utilized.

Firefox + Selenium in python: How to interactively get an element html?

Im using Python + Selenium + Splinter + Firefox to create an interactive web crawler.
The python script offers the options, then Selenium opens Firefox and sends some orders.
Right now, I need to let the python script know the web element that the user wants to interact with.
The method I currently use is:
Right-click the item in the website (Firefox), click 'inspect
element', then click in the Firefox inspector, click 'copy HTML', then
feed it manually to the script, which will then be able to go on.
But for obvious reasons I feel this process is far from perfection.
I know nothing of javascript, but after reading other questions I get the feeling that javascript could actually be the solution.
Splinter allows to run javascript and pick up the returning values into the python script, so, theoretically:
Would it be possible to run a javascript code that would return the html code of the next element the user clicks? So the named method would only be right-clicking the desired element?
Clarification for Amey's comment:
The python script opens a Firefox window, which control is still retained from the script.
And with splinter, javascript code can be executed and waited upon completion / information return.
This means that the python script can ask the user to click or right-click in the Firefox window that it owns, so the aim would be to launch a javascript that would "catch" which element the user clicks on.
Would that be enough for javascript to catch the desired element?
This was an interesting question. My strategy was to use Javascript to add listeners to the elements you're targeting. Since you didn't specify what types of elements, I used links. This could easily be adapted though.
When an element is clicked, the listener creates a new page element with an ID you specify and sets the value attribute to the relevant information.
Then, assuming you've set driver.implicitly_wait, you can just wait for the element to appear.
driver.execute_script("for(var i = 0; i < document.links.length; i++){document.links[i].onclick = function clicked(){var e = document.createElement('a'); e.setAttribute('id','myUniqueID'); e.setAttribute('value', this); document.getElementsByTagName('body')[0].appendChild(e);};}")
clicked = driver.find_element_by_id('myUniqueID').get_attribute('value')

How can a Javascript parent window send data to popup window?

I have been writing a browser based application (or rather, rapid prototyping an application) using HTML and Javascript. I would like the main window to be able to display popup windows with dynamic data. However, I cannot figure out how to push data from a parent window to a popup window in Javascript. Note, I am working with the assumption that the application may be used in "offline" scenarios, so all dynamic data should be coming from the main window.
Ideally, I'd like to write
var popup = window.open("popup.html", someidentifier, "");
popup.document.getElementById("SomeIdInPopupHtml").innerHTML = "1,2,3,4";
However, the getElementById function returns NULL. How can I push data to popup windows from a parent window?
Is the popup serving content from a different domain than the parent? If so, the short answer is you can't.
The long answer is that you can sent the popup's href fragment (i.e. the part after the # in protocol://server/path?query#fragment). If the content in the popup knows to check its fragment for changes, then you can pass data to it.
If it's from the same domain then your code should work, as long as an element with that id exists.
However, the getElementById function returns NULL.
Because popup.html hasn't loaded yet. If you want to interact with content from the document, you'll have to call back later when it has finished loading.
For completely dynamic popups, open them with a blank URL and popupwindow.document.write their content into them. For co-operatively-scripting popups loaded from a separate document, have the child document call its parent when it is ready to be accessed. Or just use in-page pop-up divs which are typically less annoyance, both for you as a coder and for the end user.
Let me start off by presenting a possible solution that I just experimented with. I would like to encourage feedback and better solutions, however...
Its not very neat, but I can append GET-style query parameters to the source URL of the popup:
var popup = window.open("popup.html?" + identifier, somename, "");
Now in my particular situation, the popup is a view to some model identified by a unique ID, so the popup window can ask for the parent window for data related to that ID:
var model = window.opener.getModel(document.location.href.split("?")[1]);
do_something_with_model(model);
This strategy won't work in all cases, especially when the data is not easily marshaled into the getModel() implementation. However, in my case, I think this approach may work.
I'd appreciate feedback on this strategy. Thanks!
When the user clicks on your link to open the popup window pass a query string to it and then react to that value with your server side code.

Categories

Resources