How can I search for a text and fill/click on a link with Selenium? - firefox

Here's the deal:
Is there a way to search for an input name or type witch is not precise and fill it?
For example, I want to fill any input with the name email with my email, but I maybe have some inputs named email-123, emailemail, emails etc... Is there a way to do something like * email * ?
And how can I click on a link verifying some text that could be on the link, or above the link, or close, or at class etc ?
ps: I'm using selenium ide with firefox

You can use Xpath to find it with something like //input[contains(#name,'email'). If you have multiple instances like that on the page it will be worth moving your test to your favourite programming language and then doing
emailInstances = sel.get_xpath_count("//input[contains(#name,'email')]")
for i in range(int(emailInstances)):
sel.type("//input[contains(#name,'email')]["+ i + 1 +"]","email#address.tld")

Xpath works well and the solution above is good. If you are trying to test old verions of IE you could also use JavaScript injection. I find it is very fast, although can be a bit trickier to debug. I didn't actually check if the below works but hopefully it gives you an idea of what you can do:
String javaScript = "_sl_enterEmailStr = function(parentObj,str) { "+
" var allTags = parentObj.getElementsByTagName('input'); "+
" for (var i = 0; i < allTags.length; ++i) { "+
" var tag = allTags[i]; "+
" if (tag.name && tag.type && tag.type === 'text' "+
" && tag.name.match(/email/)) { "+
" tag.value = str; "+
" } "+
" } "+
"}; "+
"_sl_enterEmailStr(this.browserbot.getCurrentWindow().document "+
" ,'myemail#mydomain.org'); ";
mySelenium.getEval(javaScript);
I find JavaScript injection with regular expressions allows me to do great things to dynamic input fields. Note you can use findElement() to be more specific about where you look for tags.
Regarding clicking a link and getting text, those are simple click() and getText() operations that can be done given the proper locator. I would check out the selenium API. for example, here is the link to the Java one for 1.0b2.

Related

Stanford Pattern-based Information Extraction

I really wonder how can I use SPIED (Stanford bootstrapping tool)? Is there any way to have a demo file like what we have for parsers, Ner, .....? The statement in the file is not easy to use... I'm using other tools in my project thanks to demo files...
Please see the main method of the class GetPatternsFromDataMultiClass. The static run method inside the class is almost like a demo. All you need is a properties file, an example demo properties file is provided with the release. You can also access the example properties here.
You would need to run the class with parameters: " -props [path-to-properties] "
SPIED code is different from NER etc. because there is no model released. The code is generic, like CRFs or logistic regression, which you use to train your own model.
An example code to run SPIED is (you can similarly use :
GetPatternsFromDataMultiClass<SurfacePattern> model = GetPatternsFromDataMultiClass.<SurfacePattern>run(props);
for(Map.Entry<String, Counter<SurfacePattern>> p : model.getLearnedPatterns().entrySet()){
System.out.println("For label " + p.getKey() + ", the patterns learned are: ");
for(Map.Entry<SurfacePattern, Double> pat: p.getValue().entrySet()){
System.out.println("Pattern " + pat + " with score " + pat.getValue());
}
System.out.println("For label " + p.getKey() + ", the learned words are: " + model.constVars.getLearnedWords(p.getKey()));
}
For more details on how to use the model for another piece of text, look at explanations of flags loadSavedPatternsWordsDir in the example.properties file.

How to deal with randomly generated post request parameters in Jmeter Scripts?

I am writing jmeter scripts for my web-based application. I am using firefox-firebug to watch POST request parameters. I could successfully write login page scripts because it had only "username" and "password" parameters.
But, after logging into the web application, I realized that, there are randomly generated required parameters which are sent along with the post request.
So, I am trying to find out the way to deal with these parameters.
Please let me know, if you have dealt with this situation.
Example: These are my post request parameters:
externalId=971&submit.go=Go&submit.go=&013f57c77c2a%3A6eed%3A1b320be7=105f230e-9f86-40f8-9473-215975812128
Where **013f57c77c2a%3A6eed%3A1b320be7** parameter and it's value are generated differently each time.
I don't know how to define this parameter.
I found an answer. You can use List Extractor(Regular Expression Extractor).
You can define any pattern as per your criteria.
for example regex patter is : input type="hidden" name="([^"]+?)" value="([^"]+?)"
Step2) Use Beanshell pre processor with this script.
log.info("=====================");
count = Integer.valueOf (vars.getObject("hiddenList_matchNr") ) ;
log.info("Number of hidden fields in previous sampler: " + count);
for (i=1; i <= count; i++) {
paramName = vars.getObject("hiddenList_"+ i + "_g1");
paramVal = vars.getObject("hiddenList_"+ i + "_g2");
log.info("Adding request parameter: " + paramName + " = " + paramVal);
sampler.addArgument(paramName, paramVal);
}
log.info("=====================");

Remove HTML formatting in Razor MVC 3

I am using MVC 3 and Razor View engine.
What I am trying to do
I am making a blog using MVC 3, I want to remove all HTML formatting tags like <p> <b> <i> etc..
For which I am using the following code. (it does work)
#{
post.PostContent = post.PostContent.Replace("<p>", " ");
post.PostContent = post.PostContent.Replace("</p>", " ");
post.PostContent = post.PostContent.Replace("<b>", " ");
post.PostContent = post.PostContent.Replace("</b>", " ");
post.PostContent = post.PostContent.Replace("<i>", " ");
post.PostContent = post.PostContent.Replace("</i>", " ");
}
I feel that there definitely has to be a better way to do this. Can anyone please guide me on this.
Thanks Alex Yaroshevich,
Here is what I use now..
post.PostContent = Regex.Replace(post.PostContent, #"<[^>]*>", String.Empty);
The regular expression is slow. use this, it's faster:
public static string StripHtmlTagByCharArray(string htmlString)
{
char[] array = new char[htmlString.Length];
int arrayIndex = 0;
bool inside = false;
for (int i = 0; i < htmlString.Length; i++)
{
char let = htmlString[i];
if (let == '<')
{
inside = true;
continue;
}
if (let == '>')
{
inside = false;
continue;
}
if (!inside)
{
array[arrayIndex] = let;
arrayIndex++;
}
}
return new string(array, 0, arrayIndex);
}
You can take a look at http://www.dotnetperls.com/remove-html-tags
Just in case you want to use regex in .NET to strip the HTML tags, the following seems to work pretty well on the source code for this very page. It's better than some of the other answers on this page because it looks for actual HTML tags instead of blindly removing everything between < and >. Back in the BBS days, we typed <grin> a lot instead of :), so removing <grin> is not an option. :)
This solution only removes the tags. It does not remove the contents of those tags in situations where that might be important -- a script tag, for example. You'd see the script, but the script wouldn't execute because the script tag itself gets removed. Removing the contents of an HTML tag is VERY tricky, and practically requires that the HTML fragment be well formed...
Also note the RegexOption.Singleline option. That's very important for any block of HTML. as there's nothing wrong with opening an HTML tag on one line and closing it in another.
string strRegex = #"</{0,1}(!DOCTYPE|a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdi|bdo|big|blockquote|body|br|button|canvas|caption|center|cite|code|col|colgroup|datalist|dd|del|details|dfn|dialog|dir|div|dl|dt|em|embed|fieldset|figcaption|figure|font|footer|form|frame|frameset|h1|h2|h3|h4|h5|h6|head|header|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|main|map|mark|menu|menuitem|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|small|source|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|track|tt|u|ul|var|video|wbr){1}(\s*/{0,1}>|\s+.*?/{0,1}>)";
Regex myRegex = new Regex(strRegex, RegexOptions.Singleline);
string strTargetString = #"<p>Hello, World</p>";
string strReplace = #"";
return myRegex.Replace(strTargetString, strReplace);
I'm not saying this is the best answer. It's just an option and it worked great for me.

Firefox & AJAX oddity: DOM replacements not working again after just working

these are the two functions (externally loaded):
function replaceText(element, text) {
if (element != null) {
clearText(element);
var newNode = document.createTextNode(text);
element.appendChild(newNode);
}
}
function replaceImage(element, maker, imageState) {
replaceText(element, "replacing image " + maker + " with " + imageState + " version");
var imagePath = "_img/coffeeMaker_";
if (maker != null)
{
document.getElementById("coffeeMakerImg"+ maker).src = imagePath + imageState + ".png";
}
}
now here's the part that calls these functions. *notice that the replaceText() is called from within replaceImage()
replaceText(cmStatus_01, "BREWING " + name + "'s " + size + " " + beverage);
replaceImage("feedback", "01", "full");
document.forms[0].reset();
okay. now here's the kicker: the FIRST replaceText() works fine in ALL browsers. the replaceImage() fails ONLY in Firefox which CONTAINS A CALL TO replaceText() that only JUST worked as advertised!! i could see how i might have screwed up the image replacement (even though i copy/pasted it from another working project that DOES replace the image in FF...so weird...), but i do NOT see how the replaceText() can fail: it just worked!
so: whaaaaat!? i'm thinking its some kind of scope issue, but i'm stumped as to why.
totally stumped. forehead really sore...
thank for your time and help. i'm praying this isn't something really retarded...
WR!
PS: i'm also confused why, if i remove the quotes from the element name in the replaceImage() call, it breaks; but it works in the replaceText() call without brackets just fine...
okay. i figured it out. the problem was actually what i was passing into the functions:
cmStatus_01 was NOT the actual ID of the div. it was evaluated earlier like so:
var cmStatus_01 = document.getElementById('divName');
but i WAS passing the divName into the replaceImage() function and it was expecting the evaluted version of it, like cmStatus_01. so it broke.
so when i actually retooled the function so i was ONLY passing divName, it obviously worked. this is the retool:
function replaceNodeText(id, newText)
{
var node = document.getElementById(id);
while (node.firstChild)
{
node.removeChild(node.firstChild);
}
node.appendChild(document.createTextNode(newText));
}
project deadline too tight! it's making my brain fail. :P
also: apologies for not posting where the variables came from. that would have helped enormously, i'm sure and i don't know why i didn't think to post them as well.
thank you for your patience and your time.
WR!

setAttribute, onClick and cross browser compatibility

I have read a number of posts about this but none with any solid answer. Here is my code:
// button creation
onew = document.createElement('input');
onew.setAttribute("type", "button");
onew.setAttribute("value", "hosts");
onew.onclick = function(){fnDisplay_Computers("'" + alines[i] + "'"); }; // ie
onew.setAttribute("onclick", "fnDisplay_Computers('" + alines[i] + "')"); // mozilla
odiv.appendChild(onew);
Now, the setAttribute() method (with the mozilla comment) works fine in mozilla but only if it comes AFTER the line above it. So in other words it seems to just default to whichever gets set last. The .onclick method (with the ie comment) does not work in either case, am I using it incorrectly?
Either way I can't find a way to make this work at all in IE, let alone in both. I did change the function call when using the .onclick method and it worked fine using just a simple call to an alert function which is why I believe my syntax is incorrect.
Long story short, I can't get the onclick parameter to work consistently between IE/Mozilla.
-- Nicholas
onew.setAttribute("type", "button");
Never use setAttribute on HTML documents. IE gets it badly wrong in many cases, and the DOM-HTML properties are shorter, faster and easier to read:
onew.type= 'button';
onew.onclick = function(){fnDisplay_Computers("'" + alines[i] + "'"); }; // ie
What is ‘alines’? Why are you converting it to a string and surrounding it with single quotes? It looks like you are trying to do something heinous involving evaluating code in a string (which is what you're doing below in the ‘onew.setAttribute’ version). Evaluating JavaScript code in strings is almost always the Wrong Thing; avoid it like the plague. In the above case, IE should do the same as Firefox: it shouldn't work.
If ‘alines[i]’ is a string, I guess what you're trying to do is make it remember that string by constructing a code string that will evaluate in JavaScript to the original string. But:
"'" + alines[i] + "'"
is insufficient. What happens if ‘alines[i]’ has an apostrophe in, or a backslash?
'O'Reilly'
you've got a syntax error and possible security hole. Now, you could do something laborious and annoying like:
"'" + alines[i].split('\\').join('\\\\').split("'").join("\\'") + "'"
to try to escape the string, but it's ugly and won't work for other datatypes. You could even ask JavaScript to do it for you:
uneval(alines[i])
But not all objects can even be converted to evaluatable JavaScript source strings; basically the entire approach is doomed to failure.
The normal thing to do if you just want to have the onclick callback call a function with a parameter is to write the code in the straightforward way:
onew.onclick= function() {
fnDisplay_Computers(alines[i]);
};
Generally this will work and is what you want. There is, however, a slight wrinkle which you may have hit here, which could be what is confusing you into considering the wacky approach with the strings.
Namely, if ‘i’ in this case is the variable of an enclosing ‘for’ loop, the reference to ‘alines[i]’ won't do what you think it does. The ‘i’ will be accessed by the callback function when the click happens — which is after the loop has finished. At this point the ‘i’ variable will be left with whatever value it had at the end of the loop, so ‘alines[i]’ will always be the last element of ‘alines’, regardless of which ‘onew’ was clicked.
(See eg. How to fix closure problem in ActionScript 3 (AS3) for some discussion of this. It's one of the biggest causes of confusion with closures in both JavaScript and Python, and should really be fixed at a language level some day.)
You can get around the loop problem by encapsulating the closure in its own function, like this:
function callbackWithArgs(f, args) {
return function() { f.apply(window, args); }
}
// ...
onew.onclick= callbackWithArgs(fnDisplay_Computers, [alines[i]]);
And in a later version of JavaScript, you'll be able to say simply:
onew.onclick= fnDisplay_Computers.bind(window, alines[i]);
If you would like to be able to use ‘Function.bind()’ in browsers today, you can get an implementation from the Prototype framework, or just use:
if (!('bind' in Function.prototype)) {
Function.prototype.bind= function(owner) {
var that= this;
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner,
args.length===0? arguments : arguments.length===0? args :
args.concat(Array.prototype.slice.call(arguments, 0))
);
};
};
}
I usually use something like:
onew.onclick = new Function("fnDisplay_Computers('" + alines[i] + "')");
this should work both in IE e Firefox.
Use the addEventListener() function with "click" for the type argument for Mozilla-based browsers, and attachEvent() function with "onclick" as the sEvent argument for IE; I find it best to use a try/catch statement, for example:
try {
onew.attachEvent("onclick", //For IE
function(){fnDisplay_Computers("'" + alines[i] + "'"); });
}
catch(e) {
onew.addEventListener("click", //For Mozilla-based browsers
function(){fnDisplay_Computers("'" + alines[i] + "'"); },
false);
}
I think #3 protesteth too much. In a lot of situations I'm building a table dynamically and need to pass parameters to the callback function. It isn't a typesafe issue since my variable parm is an integer index to the table row in question. Here's code with both a variable and fixed parameter that seems to be cross-browser compliant:
for (i = 0; i < arrTableData.length; i++) {
eleTR = objTable.insertRow(i + 1);
cell = eleTR.insertCell(0);
cell.width = "21";
var myElement = document.createElement('img');
myElement.setAttribute('src', 'images/button_down.gif');
myElement.setAttribute('alt', 'Move item down');
myElement.onclick = new Function('moveItem(' + i + ',0)');
cell.appendChild(myElement);
}

Resources