Python 3 Selenium fails to execute javascript - javascript

I'm using python 3 and I'm using Selenium to try to scrape data off a website. I need to remove a class from a list item in order to display the data I need, this is the code:
driver.execute_script("document.getElementsByClassName('otherClassName isSelected').classList.remove('isSelected');")
but I get the error
"selenium.common.exceptions.WebDriverException: Message: unknown error:
Cannot read property 'remove' of undefined"
I have also tried
driver.execute_script("document.getElementsByClassName('otherClassName isSelected').setAttribute('class', 'otherClassName')")
but then I get
selenium.common.exceptions.WebDriverException: Message: unknown error: document.getElementsByClassName(...).setAttribute is not a function

I guess this is because you're trying to apply class name update for multiple elements at once while setAttribute() allows to apply changes to one element at the time.
Try below code instead
js = """document.querySelectorAll('.otherClassName.isSelected')
.forEach( x=> x.setAttribute("class","otherClassName"));"""
driver.execute_script(js)
P.S. It seem to be XY problem as usually you don't need to make changes to page source while page scraping. You should share more details about your initial problem

I had forgotten to add [0] after getting the element by class, so the correct code should be:
driver.execute_script("document.getElementsByClassName('otherClassName isSelected')[0].classList.remove('isSelected');")

Related

Error: element (body) is not in DOM or there is no element(body) with text "NameTest000"

I am doing an assignment and have to create a smaller version of ecomerce website. To test it I was given a link to a their autoQA tester which gives me the following problem.
Error: element (body) is not in DOM or there is no element(body) with text "NameTest000" after 4 sec.
This error is given three times for "NameTest001" and "NameTest002". Alonside these errors the last error I was given is:
Element "delete-checkbox" was not found in text|CSS|XPath.
The thing is when I push it on the server it works as it should so I don't understand what exactly I am doing wrong. Can anyone help?
I'll link to the github repository:
https://github.com/kn000x001/scandiweb-test-nika
I'll also add the image of the error

PowerBI Javascript - Set page filters without set report filter first

Since last week when I try to apply a page filter without first setting the report filter I get an error on the console: Unhandled Promise rejection: Failed to execute 'postMessage' on 'Window': TypeError: Cannot read property 'instanceOfIVisualLevel' of undefined could not be cloned...
Using the demo it's possible to test this: https://microsoft.github.io/PowerBI-JavaScript/demo/v2-demo/index.html#
Sample Report
Click "Run"
Click "Interact"
Go to "Filters & Slicers" and click "Set page filters"
Click run to apply the page filter
Check browser console
What is the problem? Is it missing something in the demo?
It turns out that this is a problem with the Power BI Embedded back-end...
https://community.powerbi.com/t5/Developer/Problem-using-page-getFilters/m-p/511911/highlight/true#M15792
Customers may receive an error while setting or getting page-level filters or visual-level filters using the Power BI embedded javascript API. As a workaround, customers can pass in any filter object in load config. Engineers are investigating the issue. Next update # 9/10/18 at 9:00AM PDT.
As of the time of this answer however, the issue hasn't been fixed and the Power BI support page states the next update will be on 14th of September (2018), 10:00 PDT.
However, there is quite a simple work-around. Ensure you pass in an empty filter array into the embed configuration object, and everything works fine.
var embedConfig = {
...
filters: [] //Empty array of filters.
};
var $reportContainer = $('#reportContainer');
var report = powerbi.embed($reportContainer.get(0), embedConfiguration);
Then you should be able to explicitly set report/page/visual filters in whichever order you like.

How to retrieve the text of an element and write it to a file for later retrieval in protractor using angular js

So, I have to check the status of an action started by the automation script using another automation script. In order to track the action, I have to capture its Id and write it to a file which can be then read by the second script to look for the action. The problem I am having is that I am unable to get the action Id which is a number using getText(). Instead, I keep seeing other non sensical text when I check the content of the file or the variable to which I first store the Id.
The html code for action Id is:
<dd class="ng-binding">232</dd>
I am trying to capture the Id (#232 here) like this:
var Id = element(by.xpath('html/body/div[1]/div[2]/div/div[2]/div/div[2]/div[3]/dl/dd[1]')).getText();
Upon executing the automation script, the console output shows this for the var Id:
Id:[object Object]
I have verified using protractor elementExplorer that xpath points to the right element and can even extract the Id and displays it on the screen correctly. It just does not work when I am trying to store the same Id to a variable and then write to a file so that I can retrieve it for later use. Any help or hints on how to do this would be greatly appreciated.
getText() returns a promise, you have to resolve it, using absolute xpath is a bad way of locating elements. Have you tried locating with cssSelector?
element(by.css('dd.ng-binding')).getText().then(function(text) {
console.log(text);
});

Dojo 'on' event from 'byId' triggers TypeError

I have a module which contains a switch statement producing content, and a variety of on events waiting dependent on what content is inserted into the DOM and then whichever trigger is activated.
I'm finding that on event handlers using dom.byId('foo'):
on(dom.byId('foo'), touch.press, function(e){
produce the error:
Uncaught TypeError: cannot read property 'on' of null.
I can kind of understand this - if the node foo doesn't yet exist because a different switch condition has been satisfied, but i've managed to skirt this by using a css class instead:
on(query('.foo'), touch.press, function(e){
But this has the same chance of existence as the id!
I'm relatively new to Dojo, and have had "fun" getting to grips with it, and i'm interested to know why this is happening, but also if it's a Big Red Flag that i'm doing something wrong!
It's hard to say without the full code but if you want to use query you need to use this way :
require(["dojo/query"], function(query){
query(".foo").on("click", clickHandler);
});
I don't know the context of your project but if it's for mobile you maybe look at "dojo/gesture/tap" like in this exemple in the doc :
define(["dojo/on", "dojo/gesture/tap", function(listen, tap){
on(button, tap, tapHandler);
...

custom error display with parsley.js 2.x

I need to show a list of validation errors in a popup.
I've disabled UI modification with <form data-parsley-ui-enabled="false"... and subscribed to the "parsley:field:error" event, where I collect error information, and then on "parsley:form:validated" I display the popup, ofcourse only on the condition isValid() == false.
But I am having problems with getting the actual error message in the "parsley:field:error" handler. The handler gets a single parameter containing an object, which so far I inspected to have several properties:
$element - the actual jQuery field,
constraints - list of constraints
options.i18n - it has some raw error message strings which I can get iterating with an n variable like so: obj.options.i18n.<LANGUAGE_CODE>.[obj.constraints[n].name], but they ocasionally contain placeholders (%s) and therefore are not suitable for display to the end
user; and sometimes there's an array instead of a single string, which defeats the idea completely;
The question is, how do I get the actual error message which would got displayed if I hadn't disabled the UI?
Solution
Use the following way to access a prioritized error message (i.e data-parsley-priority-enabled=true):
$.listen('parsley:field:error', function(parsleyField) {
// parsley field
console.log(parsleyField);
// which constraint has failed
console.log(parsleyField.validationResult[0].assert.name);
// the data-parsley-<constraint>-message
console.log(parsleyField.options[parsleyField.validationResult[0].assert.name+'Message']);
// the default constraint fail message
console.log(window.ParsleyValidator.getErrorMessage(parsleyField.validationResult[0].assert));
});
Short Explanation
You were almost there, the messages are stored in the options object itself, and the format for the message is like this: <constraint>Message, for example: requiredMessage.
Which is similar to the "data attribute to js variable conversion" convention like in jQuery, this has been mentioned in the docs: <parsleynamespace>-<constraint>-message becomes <constraint>Message.
Got this idea after seeing the annotated source for ui.js, check the _getErrorMessage function.
To access all the validation messages for a field on error (i.e data-parsley-priority-enabled=false), you can simply iterate through the
parsleyField.validationResult array:
for (i=0; i<parsleyField.validationResult.length; i++) {
console.log(parsleyField.options[parsleyField.validationResult[i].assert.name+'Message']);
}

Categories