Best way to time something in Selenium - java

I'm writing some Selenium tests in Java, and I'm mostly trying to use verifications instead of assertions because the things I'm checking aren't very dependent so I don't want to abort if one little thing doesn't work. One of the things I'd like to keep an eye on is whether certain Drupal pages are taking forever to load. What's the best way to do that?
Little example of the pattern I'm using.
selenium.open("/m");
selenium.click("link=Android");
selenium.waitForPageToLoad("100000");
if (selenium.isTextPresent("Epocrates")) {
System.out.println(" Epocrates confirmed");
} else {
System.out.println("Epocrates failed");
}
Should I have two "waitForPagetoLoad" statements (say, 10000 and 100000) and if the desired text doesn't show up after the first one, print a statement? That seems clumsy. What I'd like to do is just a line like
if (timeToLoad>10000) System.out.println("Epocrates was slow");
And then keep going to check whether the text was present or not.

waitForPageToLoad will wait until the next page is loaded. So you can just do a start/end timer and do your if:
long start = System.currentTimeMillis();
selenium.waitForPageToLoad("100000");
long timeToLoad= (System.currentTimeMillis()-start);
if (timeToLoad>10000) System.out.println("Epocrates was slow");

Does your text load after the page is loaded? I mean, is the text inserted dynamically? Otherwise the text should be present as soon as the page was loaded.
selenium.isTextPresent
doesn't wait. It only checks the currently available page.

The best method to wait for something in Selenium is as follow:
Reporter.log("Waiting for element '" + locator + "' to appear.");
new Wait()
{
public boolean until()
{
return selenium.isElementPresent(locator);
}
}.wait("The element '" + locator + "' did not appear within "
+ timeout + " ms.", timeout);
The Waiter is part of selenium you only have to import it.
Also here is a framework that you can use. It's opensource, handles mostly everything and can be easily expanded.
https://sourceforge.net/projects/webauthfw/
Use it well and give us credit hehe. :)
Cheers,
Gergely.

In a Selenium integration test, I did it like so, using nano-time and converting to a double to get seconds:
long endTime = System.nanoTime();
long duration = (endTime - startTime);
Reporter.log("Duration was: " + ((double)duration / 1000000000.0) + " seconds.", true);
assertTrue( duration >=0 || duration <= 1000, "Test that duration of default implicit
timeout is less than 1 second, or nearly 0.");

Related

JDA Mentioned member - not working command

I am developing my bot for discord using Java and JDA API. Before that I asked a similar question, but I ran into another problem.
From this line the problems started :
final Member MentionedMem = event.getMessage().getMentionedMembers().get(0);
Thanks to https://stackoverflow.com/users/10630900/minn for answering the previous question in which he explained to me that this line is causing the error :
java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
For some reason or other it raises an error.
I was trying to find an answer to why this command does not work. The only thing I know is that this command returns an empty array args. Because of this, I cannot finish the bot, that is, I cannot check whether a member can kick others and can't make the main block of code kick members.
How can I fix this error and / or write the rest of the code?
Sorry for my English and many thanks to you.
Some code :
public class KickComm extends ListenerAdapter {
public void onGuildMessageReceived(GuildMessageReceivedEvent event) {
String[] message = event
.getMessage()
.getContentRaw()
.split(" ");
// final Member target = event.getMessage().getMentionedMembers().get(0); ERROR CUZ I DONT NOW WHY
final Member SelfMember = event
.getGuild()
.getSelfMember();
if(message[0].equalsIgnoreCase(Main.prefix + "kick"))
{
if (message.length < 2) {
EmbedBuilder NoUser = new EmbedBuilder();
NoUser.setColor(0xff3923);
NoUser.setTitle("\uD83D\uDD34You need to add a <#username> and <reason>");
NoUser.setFooter("Usage: " + Main.prefix + "kick <#username> <reason>.",
Objects
.requireNonNull(event.getMember())
.getUser()
.getAvatarUrl());
event
.getChannel()
.sendMessage(NoUser.build())
.queue();
NoUser.clear();
} else if (message.length < 3) {
EmbedBuilder NoReason = new EmbedBuilder();
NoReason.setColor(0xff3923);
NoReason.setTitle("\uD83D\uDD34You need to add a <reason>.");
NoReason.setFooter("Usage: " + Main.prefix + "kick <#username> <reason>.",
Objects
.requireNonNull(event.getMember())
.getUser()
.getAvatarUrl());
event
.getChannel()
.sendMessage(NoReason.build())
.queue();
NoReason.clear();
} else if(!SelfMember.hasPermission(Permission.KICK_MEMBERS)) {
EmbedBuilder NoPermission = new EmbedBuilder();
NoPermission.setColor(0xff3923);
NoPermission.setTitle("\uD83D\uDD34You don't have permission to use this command.");
NoPermission.setFooter("Usage: " + Main.prefix + "kick <#username> <reason>.",
Objects
.requireNonNull(event.getMember())
.getUser()
.getAvatarUrl());
event
.getChannel()
.sendMessage(NoPermission.build())
.queue();
NoPermission.clear();
} else if(!Objects.requireNonNull(event.getMember()).hasPermission(Permission.KICK_MEMBERS) || !event.getMember().canInteract(target)) { //Example, don't works
EmbedBuilder NoPermission = new EmbedBuilder();
NoPermission.setColor(0xff3923);
NoPermission.setTitle("\uD83D\uDD34You don't have permission to use this command.");
NoPermission.setFooter("Usage: " + Main.prefix + "kick <#username> <reason>.",
Objects
.requireNonNull(event.getMember())
.getUser()
.getAvatarUrl());
event
.getChannel()
.sendMessage(NoPermission.build())
.queue();
NoPermission.clear();
}
}
}
}
UPD: Please, if you downgrade, then point out the mistakes that I made, and not just downgrade it because you wanted to. I want to correct mistakes, not ruin your mood
It seems like you didn't quite get the problems in your code.
final Member target = event.getMessage().getMentionedMembers().get(0);
This will throw an IndexOutOfBoundsException if your message doesn't include a mentioned member. Because in this case the list of getMentionedMembers() is empty. There is no object to access. get(0) can't get anything.
In order to fix this you have to check first if the list is empty or if the length is zero as Minn already proposed. If it is you can display a message stating, that they need to add an #username.
Cleaning up your code and restructuring it accordingly would help a lot I suppose. Please go over it and make sure to always check, if the needed data exists in the first place and if you really need it. Some things are only needed for a small number of cases, calling them on every message / command is not good practice.
For example, at the moment your bot tries to get the first mentioned member from EVERY message that is sent. This isn't necessary hence you only need it in case it is the kick command.
By the way, the SelfMember is the bot itself. In your code you are telling the user that they don't have the permission although the bot (and not necessarily the user) might lack it which could be confusing.
I didn't see it earlier: Your bot is receiving its own messages as well. You might want to check, if the author of a message is your / a bot before continuing.
In the end I would advice you to always try to understand the answer or advice that is given to you. Asking another question for the same problem isn't going to help you nor does it cast a good light on you and your attempt to learn.
User mentionedUser = event.getMessage().getMentionedMembers().get(0).getUser();
If someone still needs it...
The issue, for some reason, was that you used Member instead of User.
Futhermore, you must use .getUser() to really get the user you want.

What is the most efficient selector to use with findElement()?

When working with Selenium web testing, there are a few ways to identify WebElements.
In my experience, I have used the following selectors:
Class Name - By.className()
CSS Selector - By.cssSelector()
ID - By.id()
Link Text - By.linkText()
Name - By.name()
Tag Name - By.tagName()
XPath - By.xpath()
Obviously, when only one option is usable to locate an element, we must use that one, but when multiple methods may be used (ex: the div below), how should it be determined which method to use? Are there selectors that are more efficient than others? Are there some that are more durable?
<div class="class" id="id" name="name">Here's a div</div>
Just for s&gs...
I timed each of the identifier methods finding the div above five separate times and averaged the time taken to find the element.
WebDriver driver = new FirefoxDriver();
driver.get("file://<Path>/div.html");
long starttime = System.currentTimeMillis();
//driver.findElement(By.className("class"));
//driver.findElement(By.cssSelector("html body div"));
//driver.findElement(By.id("id"));
//driver.findElement(By.name("name"));
//driver.findElement(By.tagName("div"));
//driver.findElement(By.xpath("/html/body/div"));
long stoptime = System.currentTimeMillis();
System.out.println(stoptime-starttime + " milliseconds");
driver.quit();
They are sorted below by average run time..
CssSelector: (796ms + 430ms + 258ms + 408ms + 694ms) / 5 = ~517.2ms
ClassName: (670ms + 453ms + 812ms + 415ms + 474ms) / 5 = ~564.8ms
Name: (342ms + 901ms + 542ms + 847ms + 393ms) / 5 = ~605ms
ID: (888ms + 700ms + 431ms + 550ms + 501ms) / 5 = ~614ms
Xpath: (835ms + 770ms + 415ms + 491ms + 852ms) / 5 = ~672.6ms
TagName: (998ms + 832ms + 1278ms + 227ms + 648ms) / 5 = ~796.6ms
After reading #JeffC 's answer I decided to compare By.cssSelector() with classname, tagname, and id as the search terms. Again, results are below..
WebDriver driver = new FirefoxDriver();
driver.get("file://<Path>/div.html");
long starttime = System.currentTimeMillis();
//driver.findElement(By.cssSelector(".class"));
//driver.findElement(By.className("class"));
//driver.findElement(By.cssSelector("#id"));
//driver.findElement(By.id("id"));
//driver.findElement(By.cssSelector("div"));
//driver.findElement(By.tagName("div"));
long stoptime = System.currentTimeMillis();
System.out.println(stoptime-starttime + " milliseconds");
driver.quit();
By.cssSelector(".class"): (327ms + 165ms + 166ms + 282ms + 55ms) / 5 = ~199ms
By.className("class"): (338ms + 801ms + 529ms + 804ms + 281ms) / 5 = ~550ms
By.cssSelector("#id"): (58ms + 818ms + 261ms + 51ms + 72ms) / 5 = ~252ms
By.id("id") - (820ms + 543ms + 112ms + 434ms + 738ms) / 5 = ~529ms
By.cssSelector("div"): (594ms + 845ms + 455ms + 369ms + 173ms) / 5 = ~487ms
By.tagName("div"): (825ms + 843ms + 715ms + 629ms + 1008ms) / 5 = ~804ms
From this, it seems like you should use css selectors for just about everything you can!
In my experience, I use these locators in this order:
id
linkText/partialLinkText
CSS Selector
XPath
The others: class name, tag name, name, etc. can all be found using CSS selectors. I rarely need a single class name so I prefer CSS selector so that I can use more than one class but also specify a tag name to make it more specific and less likely to break. Tag name is rarely used... unless we are talking about a TABLE or TR or TD tags and those can all be done with CSS Selectors. I generally find that tags with a name also have an id so I prefer id.
I recently found, as you did in your answer, that CSS selector is the fastest. This makes sense because Selenium is using the browser to do the searches and CSS selectors are so common that the different browsers have optimized performance for their use.
linkText/partialLinkText are very specialized so I don't really count them. I use them when I can and it makes sense. I have thought about just using By.cssSelector("#someId") but I don't think it really makes that much of a difference and By.id() is just a little more obvious when using an Id.
I rarely use XPath and only when I can't accomplish it with other locators, e.g. in the case of text from a tag or some weird child/descendant thing that I can't do with CSS selectors. I found (and read) that XPath support is varied by browser and it's slower so I avoid it unless absolutely necessary... and I have found you can locate 99% of elements with #1-3.
ids should be the most durable. LinkText and partialLinkText are probably fairly durable, depending on the page. Classes applied and the structure of the HTML that you would use with CSS selectors are probably the most likely to change with a page update. It really depends on the size of the update as to whether a partial portion of a page is changed. CSS Selectors and XPath would both (generally) be affected by these sorts of changes.
In the end... as long as you aren't scraping the page for hundreds of elements, one page transition is likely to be WAY more significant than a few hundred ms of difference between locator methods.
I'd prioritise selectors like this:
ID - By.id()
Name - By.name()
CSS Selector - By.cssSelector()
XPath - By.xpath()
Tag Name - By.tagName()
Link Text - By.linkText()
However, uniq IDs and Names are not always exist. Also you can use CSS Selectors to locate by ID #element_id or by Name [name=element_name] or by ClassName .element_class, so might be good idea to use CSS Selectors instead ID, Name and ClassName. Css is faster than xPath, so it's better to use it where possible. xPath is good for difficult element locators which CSS Selectors can't find. I also wouldn't use Tag Name and Link Text as you can write the same with xPath(For Link Text //a[text()='link_text'], Tag Name //div) or CSS Selectors(For Tag Name div ).
Locators should be descriptive, unique, and unlikely to change. So my priority is as follows:
ID - You'll get the exact element you want and it can be descriptive and won't be changed by mistake.
Class - Very descriptive, probably unique in context of parent element.
CSS - Better performence than XPath - see Dave Haeffner's great benchmark.
XPath - Has capabilities that CSS doesn't like Axis e.g. ::parent and functions like contains().
I would avoid LinkText and TagName as they tend to cause unexpected failures due to very generic filtering.
Note on CSS and XPath: Using these with something like //div/li[1]/*/span[2] or div > li:nth-child(1) should also be avoided as they depend on the rendering and prone to changes.

Camunda - executing processes in specific order

Let's say that we have bussiness process A. Process A might take more or less time (it's not known).
Normally you can have multiple A processes, but sometimes during some operations we need to make sure that one process execution is made after previous one.
How can we achieve it in Camunda? Tried to find something like process dependency (so process starts after previous one is complete), but couldn't find anything :(
I thought about adding some variable in process (like depending_process) and checking if specified process is done, but maybe there would be some better solution.
Ok, after some research I got solution.
On the beginning of every process I check for processes started by current user:
final DateTime selfOrderDate = (DateTime) execution.getVariable(PROCESS_ORDER_DATE);
List<ProcessInstance> processInstanceList = execution
.getProcessEngineServices()
.getRuntimeService()
.createProcessInstanceQuery()
.processDefinitionId(execution.getProcessDefinitionId())
.variableValueEquals(CUSTOMER_ID, execution.getVariable(CUSTOMER_ID))
.active()
.list();
int processesOrderedBeforeCurrentCount = 0;
for (ProcessInstance processInstance : processInstanceList) {
ExecutionEntity entity = (ExecutionEntity) processInstance;
if (processInstance.getId().equals(execution.getId()))
continue;
DateTime orderDate = (DateTime) entity.getVariable(PROCESS_ORDER_DATE);
if (selfOrderDate.isAfter(orderDate)) {
processesOrderedBeforeCurrentCount += 1;
}
}
Then I save number of previously started processes to Camunda and in next task check if it's equal to 0. If yes, I proceed, if nope, I wait 1s (using Camunda's timer) and check again.

Encog - EarlyStoppingStrategy with validation set

I would like to stop training a network once I see the error calculated from the validation set starts to increase. I'm using a BasicNetwork with RPROP as the training algorithm, and I have the following training iteration:
double validationError = 999.999;
while(!stop){
train.iteration(); //weights are updated here
System.out.println("Epoch #" + epoch + " Error : " + train.getError()) ;
//I'm just comparing to see if the error on the validation set increased or not
if (network.calculateError(validationSet) < validationError)
validationError = network.calculateError(validationSet);
else
//once the error increases I stop the training.
stop = true ;
System.out.println("Epoch #" + epoch + "Validation Error" + network.calculateError(validationSet));
epoch++;
}
train.finishTraining();
Obviously this isn't working because the weights have already been changed before figuring out if I need to stop training or not. Is there anyway I can take a step back and use the old weights?
I also see the EarlyStoppingStrategy class which is probably what I need to use by using the addStrategy() method. However, I really don't understand why the EarlyStoppingStrategy constructor takes both the validation set and the test set. I thought it would only need the validation set and the test set shouldn't be used at all until I test the output of the network.
Encog's EarlyStoppingStrategy class implements an early stopping strategy according to this paper:
Proben1 | A Set of Neural Network Benchmark Problems and Benchmarking Rules
(a full cite is included in the Javadoc)
If you just want to stop as soon as a validation set's error no longer improves you may just want to use the Encog SimpleEarlyStoppingStrategy, found here:
org.encog.ml.train.strategy.end.SimpleEarlyStoppingStrategy
Note, that SimpleEarlyStoppingStrategy requires Encog 3.3.

One (log.isDebugEnabled()) condition each debug statement occurrence

I would like to check with the community, if this is an accepted practice, to have multiple if conditions for each debug statement occurring in a row:
if (log.isDebugEnabled()) log.debug("rproductType = "+ producteType);
if (log.isDebugEnabled()) log.debug("rbundleFlag = " + bundleFrlag);
if (log.isDebugEnabled()) log.debug("rmrktSegment = " + mrktSeegment);
if (log.isDebugEnabled()) log.debug("rchannelTy = " + channelrTy);
if (log.isDebugEnabled()) log.debug("rcompanyPartner = " + coempanyPartner);
if (log.isDebugEnabled()) log.debug("rpreSaleDate = " + preSaleDaete);
if (log.isDebugEnabled()) log.debug("rportNC = " + portrNC);
if (log.isDebugEnabled()) log.debug("rLDC debug end");
I am personally supportive of have a single if condition to wrap up the entire log statements since they are appearing in a row. What are your inputs on this? Or do you see why the original author had wanted to have an if condition for each debug statement?
Thanks!
At best, it is messy. At worst, it performs absolutely redundant function calls.
The only potential difference in logic between sharing ifs is if the debugging option is somehow changed mid-call (possibly by a config reload). But capturing that extra half-a-call really isn't worth the wall of gross code.
Just change it. Don't Repeat Yourself
The reason the if is there at all is to avoid the overhead of building the debug strings if you aren't in debug mode; that part you should keep (Or not keep, if you find this is not a performance critical part of your application).
Edit FYI, by "change it", I mean do this instead:
if (log.isDebugEnabled())
{
log.debug("rproductType = "+ producteType);
log.debug("rbundleFlag = " + bundleFrlag);
// etc
}
The if condition is in there for increased speed.
It is intended to avoid the computational cost of the disabled debug statements. That is, if you have your log level set to ERROR, then there is no need to create the actual message.
http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Category.html
My personal feeling is that the
if (log.isDebugEnabled())
statments are a micro-optimization that just makes the code harder to read.
I know this was once a best practice for log4j, but many of those checks are performed prior the log staments themselves ( you can see in the source code ) and the only operations you are saving yourself is the string concatenations. I would remove them.
I would do it like that:
if (log.isDebugEnabled()) {
StringBuilder builder = new StringBuilder();
builder.append("rproductType = ");
builder.append(producteType);
builder.append("rbundleFlag = ");
builder.append(bundleFrlag);
builder.append("rproductType = ");
builder.append(mrktSeegment);
builder.append("rchannelTy = ");
builder.append(channelrTy);
builder.append("rcompanyPartner = ");
builder.append(coempanyPartner);
builder.append("rpreSaleDate = ");
builder.append(preSaleDaete);
builder.append("rportNC = ");
builder.append(portrNC);
builder.append("rLDC debug end");
log.debug(builder.toString());
}
You have only 2 isDebugEnabled checks in this code: one at the beginning, one in log.debug. The first one prevents the creation of the builder and several short living objects (you heap will thank you)
The second one is obsolet in this case. But it is an pretty easy check, so I think the cost the builder would be higher. Given the fact that in most production system the debug level is off, I think this is the best option.
To summarize, I use isDebugEnabled when my debug statement - or anything else what I need to do for my debug message - becomes more complex then usual. In most cases this is when it comes to String concatenations.
Never use isDebugEnabled for single line log statements. As it has been already mentioned. the log.debug method calls it itself.
Cheers
Christian
Depends. Log4j does this very check at the beginning of every method—isDebugEnabled() before debug statement, isWarnEnabled() before warn, etc.,—by default.
This does not mean checks are not required. Checks can save procssing if any of the parameters passed invoke computation. E.g., LOGGER.debug(transformVars(a, b, c, d)); would result in unnecessary execution of transform(), if debug is not enabled!

Categories