No node found for selector // Puppeteer Error - javascript

Im trying to build a simple program that checks my college portal and notifies me when the portal changes.
I used Chrome's inspect feature to copy the selector but still error occurs.
I used the selector that pops on when I put my mouse on top of the source code and the error still occurs.
The only solution I found was to actually right click the button I want to find the selector for, then click inspect and then go back to the console and look up the selector.
How can I solve this problem?
await page.waitFor(10000);
await page.click('a#SLO_SS_STDNTCEN_SLO_SS_APP_STATUS.PSHYPERLINK');
await page.waitForSelector('a#SLO_SS_STDNTCEN_SLO_SS_APP_STATUS.PSHYPERLINK');
await page.click('a#SLO_SS_STDNTCEN_SLO_SS_APP_STATUS.PSHYPERLINK');
I expected for the computer to click on the selector I chose- which is correct without a doubt- but an error occurs: No node found for selector

Related

Cypress - Aseertions on array properties

I have yielded some iframe and acessed to its body.
Now i'm trying to make an assertions that an 'href' property exists but can't do it.
See the response (sorry cant post images not as links yet)
1 - can see that i have an acess to the properties
2 - cy.wrap() error that says :
Timed out retrying after 50000ms: cy.should() failed because this element is detached from the DOM.
Cypress requires elements be attached in the DOM to interact with them.
The previous command that ran was:
cy.wrap()
This DOM element likely became detached somewhere between the previous and current command.
Common situations why this happens:
Your JS framework re-rendered asynchronously
Your app code reacted to an event firing and removed the element
Couldnt understand the cy.wrap() error, i can clearly see the properties of the body but can't access them ? how come ?
Feels like i am missing some basic stuff and can be laughed at, but anyway...
That is the part of the test
const iframe = cy.get('*[class^="cbola-banner__tag"]')
.find('iframe')
.its('0.contentDocument.body')
.then(cy.wrap)
iframe.children()
.should('have.a.property', 'href')
I'm expecting to make an assertion that some of the properties exists.

Elements Not Selectable Until Inspected in Dev Tools

Fascinating situation.
I am trying to select elements by class name, just by typing in the Chrome Dev Tools console. I can see the elements that I want to select and they are visible on the page. I wait 3+ seconds for the page to load before I go directly to the Dev Console and type:
document.getElementsByClassName("example");
>> HTMLCollection []
Then, I right click on the element in question and hit "Inspect". I then return to the console and type:
document.getElementsByClassName("example");
>> HTMLCollection [div.example.row]
So now the elements are there! But I did nothing in Dev Tools when inspecting the elements other than hover over them. Can someone help explain this mystery? Thanks so much.
If it's any explanation, I am using Quovo. Here is a demo: https://youtu.be/lPcIYupa2kY.
I figured out that in this case the issue was actually that the element in question was in an iframe. Ran into this issue here: SecurityError: Blocked a frame with origin from accessing a cross-origin frame.
What you are describing is really not all that "fascinating". It's really just a matter of understanding how the console reports values.
When you type:
document.getElementsByClassName("example");
the console will respond by reporting what the return value of that statement is. getElementsByClassName() returns a node list (also known as an HTML Collection) and so that's just what the console shows you:
HTMLCollection []
The elements were there the whole time. If you were to type:
document.getElementsByClassName("example")[0];
The console would report on that particular DOM element. And, if you were to type:
document.getElementsByClassName("example").length;
The console would report the number of elements within that collection.
But, when you inspect an element, you are telling the console that you are interested in just one element and, while each vendor's development tools are built differently, they are all going to show content that is in the scope of that inspected element. So, when you return to the console and try your code again, you get the same collection as before, but with the inspected item taking center stage.
Essentially, this all just boils down to knowing how to interpret the console output. It is not a matter of the DOM being ready in one case and not in another.
If you were to set up a DOMContentLoaded event handler and try your code in there, you'd see that your code works correctly all the time.

How to clear a specific / particular error from browser console using code?

I want to clear one specific error that prints in browser console. I don't want to use try catch or any other thing and not display it.
I want it to be displayed and than clear it. Something like clearing the last error or previous error from console is fine as well

Python back to previous page with remembering the elements

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

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')

Categories

Resources