We are migrating from Protractor to using SeleniumWebdriver for Node.js:
https://www.npmjs.com/package/selenium-webdriver
Using Protractor for AngularJS, we can do:
element.all(by.repeater('r in roles')).first().element(by.css('.update-role')).click();
I am trying to figure out what an equivalent call might look like using require('selenium-webdriver'), anybody have an idea?
Specifically, the by.repeater() call, is what I don't know an equivalent for.
this is fairly simple. you need to find all the elements, and treat them as similar elements.
element.all(by.css('[ng-repeat="r in roles"]')).then(function(eachRepeat){
for(var i=0;i<eachRepeat.length; i++){
// do something else with the repeat. where eachRepeat[0] is the first element
console.log(eachRepeat[i]);
}
});
you could also add a condition for the element number. or element's text.
element.all(by.css('[ng-repeat="r in roles"]')).getText().then(function(eachRepeat){
for(var i=0;i<eachRepeat.length; i++){
console.log(eachRepeat[i]);
if(eachRepeat[i] === 'someSpecificText'){
eachRepeat[i].click();
}else{
console.log('error');
}
}
});
Let me know if you have any questions on this.
Related
I have this piece of code that encodes an array of results from a database search:
foreach($searchResults[$i] as $key => $value) {
$searchResults[$i][$key] = rawurlencode($value);
}
I had to encode in order to pass the data as JSON to another page. On the other page, I'm trying to decode the resulting object like this in Javascript:
if (results !== null) {
for (var i = 0; i < results.length; i++) {
$.each(results[i], function (key, value) {
results[i][key] = decodeURIComponent(results[i][key]);
});
}
}
My problem is that I'm getting a URIError due to malformed URI. There are several pieces of data being passed, so my real question is if there is some method or tool that allows you to search an array of strings for the offending item. I have several results and don't relish the idea of having to go through them character by character to find the offending encoding. Does anyone have any suggestions? If I could figure out what character/characters is causing this error I would be on my way to figuring out a solution. I'm a coding newbie, so please forgive any incorrect use of terminology.
BTW - Sometimes this code works perfectly... I'm trying to find a way to narrow down the offending database items that are causing this error to occur periodically.
After this question:
How set a function into limits parameters on multer?
that it doesn't receive an answer, I'm looking for an alternative and I'm seeing formidable.
I found different tutorial and now I have this code:
exports.formidable= function (req, res, cb){
var form = new formidable.IncomingForm();
form.multiples = true;
form.parse(req, function(err, fields, files) {
res.end(util.inspect({fields: fields, files: files}));
});
form.on('end', function(fields, files) {
for(var i = 0; i < this.openedFiles.length; i++) {
/* Temporary location of our uploaded file /
var temp_path = this.openedFiles[i].path;
/ The file name of the uploaded file /
var file_name =Date.now()+"-"+ this.openedFiles[i].name;
/ Location where we want to copy the uploaded file */
var new_location = './files/';
fs.move(temp_path, new_location + file_name, function (err) {
if (err) {
console.error(err);
} else {
console.log("success!")
}
});
}
});
return;
};
Now, if I iterate files in the first part of the code I receive some thing like [{input_file1:{file's attributes}},
{input_file2:{file's attributes}}]
and iterating openedFiles:
[{0: {file's attributes},
{1:file's attributes}}]
Now, can I be certain the both objects are in the same order?
And, if the answer, as I suppose, is not, can I retrieve the input name from the second object?
If it's impossible, there are some workaround to do that?
Thanks for your help!
I found a "dirty" solution but for now it works fine so I want share with you my code.
In rules_upload.js I add this code:
var tmp='';
var x=0;
form.on('fileBegin', function(name, file) {
if(x>0)
{
this.openedFiles[(x-1)].fieldName=tmp;
}
x++;
tmp=name;
});
form.on('end', function(fields, files) {
this.openedFiles[(this.openedFiles.length-1)].fieldName=tmp;
So I adda new attribute called fieldName to retrieve this information!
I have a small jQuery plugin, which takes a list of divs (which contain links and images) and turns them into a list you can scroll through by clicking up and down arrows.
I'm writing automated tests using selenium-webdriver, and the tests are written in Node + Chai and are run using Mocha. One of the tests scrolls all the way to the bottom of the list by clicking the down arrow a bunch of times, and right now that code looks like this:
driver.findElement(by.css('.module-slider-1 > div.next_arrow')).click().then(function() {
driver.findElement(by.css('.module-slider-1 > div.next_arrow')).click().then(function() {
driver.findElement(by.css('.module-slider-1 > div.next_arrow')).click().then(function() {
driver.findElement(by.css('.module-slider-1 > div.next_arrow')).click().then(function() {
driver.findElement(by.css('.module-slider-1 > div.next_arrow')).click().then(function() {
driver.findElement(by.css('.module-slider-1 > div.next_arrow')).click().then(function() {
expect('.module-slider-1 div.moduleItem.active img').dom.to.have.attribute('src', slider1FinalTopImg);
});
});
});
});
});
});
Basically, I'd like to be able to click on an element multiple times without having to nest the code this much.
It's tough finding an answer to this question via Google or the docs, as most searches return results for Python, Java, or C#. Any help would be appreciated!
Recursion would of course be quite an easy way - wrap the call in a function and call it again in then block until satisfied. Or since it looks like you have a bunch of promises at hand you should be able to do (untested)
var clicketyclick = function() {
return driver.findElement(by.css('.module-slider-1 > div.next_arrow')).click();
};
clicketyclick()
.then(clicketyclick)
.then(clicketyclick)
.then(clicketyclick)
.then(clicketyclick)
.then(clicketyclick)
.then(function() {
expect(...);
});
I've gone through: https://code.google.com/p/selenium/wiki/WebDriverJs and it doesn't have any information. So, can someone help.
I have
var element = driver.findElements(webdriver.By.id("something"))
console.log('text='+element.getAttribute("innerHTML"));
But doesn't work. Most of the documentation appears to be for JAVA not nodeJS. If you come across a .getText() function, I'm pretty sure that is JAVA. I actually just want the text part innerText, opposed to innerHTML. But that might be asking too much.
You can check innerHTML like this:
driver.executeScript(function() {
return document.querySelector('#something').innerHTML;
}).then(function(innerHTML) {
//check content here
});
Per the webdriver.js docs:
var myElement = element(by.css('.myclass'));
myElement.getInnerHtml().then(function(html) {
//do stuff with html here
});
Hope that helps! It's working for me using Node.js + Selenium / WebDriver, etc.
I was wondering if there are ways to convert MathJax output to MathML.
I read through several articles that saying MathJax supports MathML. I can also see the option 'Show MathML' when I right click the MathJax formulas. My question is, can I get the MathML output to the webpage from MathJax? I am not familiar with MathJax and I am not sure how it works. Any resources or tutorial pages would have been nice!
#Peter, I think the OP may be asking how to get a MathML string from MathJax, rather than how to insert the MathML tags into the page directly. So perhaps the discussion on the MathJax forums that describes how to use toMathML will do the trick.
The basic idea is to get the element jax (using MathJax.Hub.getAllJax) for the math you want to convert, then to call its toMathML method. But you need to use some care for this, as toMathML can operate asynchronously. The link above goes through the details.
EDIT: The MathJax-node project allows you to do this from the command line, so you might want to check that out as well.
I have written some code check it out:
First include "https://code.jquery.com/jquery-1.11.2.min.js" and "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
var JaxToML = {
toMathML: function(jax, callback) {
var mml;
try {
mml = jax.root.toMathML("");
} catch (err) {
if (!err.restart) {
throw err
} // an actual error
return MathJax.Callback.After([JaxToML.toMathML, jax, callback], err.restart);
}
MathJax.Callback(callback)(mml);
},
convert: function(AjaxText, callback) {
var tempDiv = $('<div style="width:455px;height:450px:border-width:thick;border-style:double;"></div>').appendTo("body").html(AjaxText)[0];
MathJax.Hub.Queue(["Typeset", MathJax.Hub, tempDiv]); //first place in Q
MathJax.Hub.Queue(function() { //wait for a callback to be fired
var jax = MathJax.Hub.getAllJax(tempDiv);
for (var i = 0; i < jax.length; i++) {
JaxToML.toMathML(jax[i], function(mml) {//alert(jax[i].originalText + "\n\n=>\n\n"+ mml);
AjaxText = AjaxText.replace(jax[i].originalText, mml);
});
}
$(tempDiv).remove();
AjaxText = AjaxText.replace(/\(/g,""); //notice this escape character for ( - i.e it has to be \( , know why it is beacuse JS will treat ) or ( as end/begin of function as there are no quotes here.
AjaxText = AjaxText.replace(/\)/g,""); //notice this escape character for ) - i.e it has to be \)
AjaxText = AjaxText.replace(/\\/g,"");
callback(AjaxText);
});
},
};
Usage :
JaxToML.convert(AjaxText, function(mml) {
alert(mml);
});
The MathJax documentation on configuring MathJax is probably the place to start reading. You can configure the output jax per browser.
A word of caution. There's a reason why MathJax does not use to MathML output on any browser right now: browser support isn't quite there yet. (This will change as browsers catch up and MathJax can start to leverage their native support.) So make sure your content actually renders ok.