Locating element by id fails in Selenium 2.0 Webdriver - webdriver

I'm using Selenium 2.0 web driver. My script fails occasionally whenever I try locating something in my page. It throws an exception:
Unable to locate element: {"method":"id","selector":"username"};
part of my code:
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
WebElement userName = driver.findElement(By.id("username"));
userName.clear();
userName.sendKeys("admin");
It passes successfully sometimes with the same code. I don't understand what's happening.

Sometimes this happens because of the page is loading slowlier than you expected. I am doing workaround by applying my own wrapper helper. It looks like this:
private WebElement foundElement;
public WebElement find(By by){
for (int milis=0; milis<3000; milis=milis+200){
try{
foundElement = driver.findElement(by);
}catch(Exception e){
Thread.sleep(200);
}
}
return foundElement;
}
And later in the code:
WebElement userName = find(By.id("username"));
This approach will try to find it and if not found, sleep for 200 miliseconds and try again. If not found in 3 seconds (editable), it will crash (you will probably have to say in the method that it throws some Exception)
I apply it whenever I am not sure how fast the page will load...

The best solution to your problem is by making the driver wait until the id element loads in the browser by using the WebDriverWait Object -
new WebDriverWait(driver, 10).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver arg0) {
WebElement element = driver.findElement(By.id("username"));
return element.isDisplayed();
}
});
This makes sure that the driver stops checking if the id element has loaded. If it does not load within 10 secs an timedOutException will be thrown.

Related

SQLite used through sqlite4java program does not end

I have a sqlite4java program to connect and run statements on my SQLite database like this in my main method:
public static void main(String[] args) throws SQLiteException {
getPredictions();
}
private static void getPredictions() throws SQLiteException {
int passValue = 408;
SQLiteConnection db = new SQLiteConnection(new File("D:\\sqlite\\CW.db"));
db.open(true);
SQLiteStatement statement = db.prepare("SELECT * FROM user_based_sim WHERE user1 = ? OR user2 = ?;");
try {
statement.bind(1,passValue);
statement.bind(2,passValue);
while (statement.step()) {
System.out.println(statement.columnInt(0));
}
} finally {
statement.dispose();
}
db.dispose();
}
}
The statement prints the right values etc but the program does not end, eg this remains like this until I shut it down manually:
IntelliJ run/stop buttons
Looks to me the while loop doesnt halt, not sure why. I follow the documentation precisely.
I think there might be something else that's going on there, some other thread gets started and never terminates. Just to make sure, I ran the same code that you posted and it terminated fine. Or, possibly, there's something wrong with the database file and SQLite just keeps scanning it after the first result was printed.
To figure out what's going on, run your program in IDEA, and when it hangs in the end, use the "Dump Threads" action in IDEA (a camera-like icon). If that doesn't answer the question right away, please post the thread dump here.
Hope this helps!
Igor

Webdriver not saving entries

I have a simple login page that I am testing using Webdriver. I have the user and password fields declared as webelements, which I look by id. Same with the sign-up button. I populate the user, and password fields before hitting sign-up, but things happen so fast, that it looks like sign up gets clicked before the user and p/w fields get populated, thereby always resulting in an error stating that the two fields cannot be empty. This does not always happen though. To be sure, I inserted a Thread.sleep after user and password setters, but didn't see any change. I can see that the fields get filled, and there is a wait time (which I introduced through sleep), but when the sign-up button is clicked, the user and password fields become red again as if they were not filled before hitting continue. I used Webdriver's fluent API to make sure the buttons are all available to be clicked, but that also didn't make a difference. Has anyone seen this behavior before? How did you solve it? (I haven't attached a code snippet here, since the scenario is really very basic).
Edit : Attaching the code snippet here :
#FindBy(id = "signUp_id")
WebElement signUpButton;
#FindBy(id = "UserName")
WebElement userNameElement;
#FindBy(id = "Password")
WebElement passwordElement;
writeInTextField(call(By.id("UserName")), userName);
writeInTextField(call(By.id("Password")), password);
Thread.sleep(10000);
call(By.id("signUp_id")).click();
public WebElement call(final By locator) {
WebElement webElement = fluentWait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
});
return webElement;
}
public void writeInTextField(WebElement we, String sText) {
we.clear();
we.sendKeys(sText);
}
I initialize fluentWait variable as :
fluentWait = new FluentWait<WebDriver>(driver).withTimeout(waitTimeOutInSeconds,
TimeUnit.SECONDS).pollingEvery(pollingInterval,
TimeUnit.MILLISECONDS).ignoring(NoSuchElementException.class,
StaleElementReferenceException.class);
This is more of common,
f developers have used any js based actions to verify fields are filled properly.
You should try entering "tab" character after doing "sendKeys". And then it should work.
I am using qaf, which has listeners capabilities and I am doing 'clear" of webelement via listener whenever click happens which makes actual code look clean.

CannotOpen exception when trying to reopen same database

I'm trying to close a current SQLite connection and reopen a new one.
But sometimes, it's actually the same one (DB name is based on my user ID after login).
This fails with the below exception:
SQLite.SQLiteException occurred
_HResult=-2146233088
_message=Could not open database file: one.sql (CannotOpen)
HResult=-2146233088
Message=Could not open database file: one.sql (CannotOpen)
Source=Cirrious.MvvmCross.Plugins.Sqlite.WindowsPhone
StackTrace:
at SQLite.SQLiteConnection..ctor(String databasePath, Boolean storeDateTimeAsTicks)
InnerException:
To test, I've modified N-10-KittensDb, with the below code:
public DataService(ISQLiteConnectionFactory factory)
{
using (_connection = factory.Create("one.sql"))
{
_connection.CreateTable<Kitten>();
}
using (_connection = factory.Create("one.sql"))
{
_connection.CreateTable<Kitten>();
}
}
Why it would fail on the second using with above exception?
I've already tried calling Close(), Dispose() manually, settting connection var to null and calling GC.Collect, but nothing seems to fix this.
If I close the program and restart new, it works fine.
Looks like the file is in use or similar...
I've debugged until before the SQLlite3 code, and this line in the SQLiteConnection constructor:
var r = SQLite3.Open(DatabasePath, out handle);
is the one returning CannotOpen.
Any idea that could help me pass this, aside from closing the app?
Closing the app could be a possibility, but looks like a to strong solution, as my user is just pressing the "log-out" button.

nhibernate transactions and unit testing

I've got a piece of code that looks like this:
public void Foo(int userId)
{
try {
using (var tran = NHibernateSession.Current.BeginTransaction())
{
var user = _userRepository.Get(userId);
user.Address = "some new fake user address";
_userRepository.Save(user);
Validate();
tran.Commit();
}
}
catch (Exception) {
logger.Error("log error and don't throw")
}
}
private void Validate()
{
throw new Exception();
}
And I'd like to unit test if validations ware made correctly. I use nunit and and SQLLite database for testing. Here is test code:
protected override void When()
{
base.When();
ownerOfFooMethod.Foo(1);
Session.Flush();
Session.Clear();
}
[Test]
public void FooTest()
{
var fakeUser = userRepository.GetUserById(1);
fakeUser.Address.ShouldNotEqual("some new fake user address");
}
My test fails.
While I'm debugging I can see that exception is thrown, Commit has not been called. But my user still has "some new fake user address" in Address property, although I was expecting that it will be rollbacked.
While I'm looking in nhibernate profiler I can see begin transaction statement, but it is not followed neither by commit nor by rollback.
What is more, even if I put there try-catch block and do Rollback explicitly in catch, my test still fails.
I assume, that there is some problem in testing environment, but everything seems fine for me.
Any ideas?
EDIT: I've added important try-catch block (at the beginning I've simplified code too much).
If the exception occurs before NH has flushed the change to the database, and if you then keep using that session without evicting/clearing the object and a flush occurs later for some reason, the change will still be persisted, since the object is still dirty according to NHibernate. When rolling back a transaction you should immediately close the session to avoid this kind of problem.
Another way to put it: A rollback will not rollback in-memory changes you've made to persistent entities.
Also, if the session is a regular session, that call to Save() isn't needed, since the instance is already tracked by NH.

java.lang.IllegalStateException: Cannot (forward | sendRedirect | create session) after response has been committed

This method throws
java.lang.IllegalStateException: Cannot forward after response has been committed
and I am unable to spot the problem. Any help?
int noOfRows = Integer.parseInt(request.getParameter("noOfRows"));
String chkboxVal = "";
// String FormatId=null;
Vector vRow = new Vector();
Vector vRow1 = new Vector();
String GroupId = "";
String GroupDesc = "";
for (int i = 0; i < noOfRows; i++) {
if ((request.getParameter("chk_select" + i)) == null) {
chkboxVal = "notticked";
} else {
chkboxVal = request.getParameter("chk_select" + i);
if (chkboxVal.equals("ticked")) {
fwdurl = "true";
Statement st1 = con.createStatement();
GroupId = request.getParameter("GroupId" + i);
GroupDesc = request.getParameter("GroupDesc" + i);
ResultSet rs1 = st1
.executeQuery("select FileId,Description from cs2k_Files "
+ " where FileId like 'M%' and co_code = "
+ ccode);
ResultSetMetaData rsm = rs1.getMetaData();
int cCount = rsm.getColumnCount();
while (rs1.next()) {
Vector vCol1 = new Vector();
for (int j = 1; j <= cCount; j++) {
vCol1.addElement(rs1.getObject(j));
}
vRow.addElement(vCol1);
}
rs1 = st1
.executeQuery("select FileId,NotAllowed from cs2kGroupSub "
+ " where FileId like 'M%' and GroupId = '"
+ GroupId + "'" + " and co_code = " + ccode);
rsm = rs1.getMetaData();
cCount = rsm.getColumnCount();
while (rs1.next()) {
Vector vCol2 = new Vector();
for (int j = 1; j <= cCount; j++) {
vCol2.addElement(rs1.getObject(j));
}
vRow1.addElement(vCol2);
}
// throw new Exception("test");
break;
}
}
}
if (fwdurl.equals("true")) {
// throw new Exception("test");
// response.sendRedirect("cs2k_GroupCopiedUpdt.jsp") ;
request.setAttribute("GroupId", GroupId);
request.setAttribute("GroupDesc", GroupDesc);
request.setAttribute("vRow", vRow);
request.setAttribute("vRow1", vRow1);
getServletConfig().getServletContext().getRequestDispatcher(
"/GroupCopiedUpdt.jsp").forward(request, response);
}
forward/sendRedirect/sendError do NOT exit the method!
A common misunderstanding among starters is that they think that the call of a forward(), sendRedirect(), or sendError() would magically exit and "jump" out of the method block, hereby ignoring the remnant of the code. For example:
protected void doXxx() {
if (someCondition) {
sendRedirect();
}
forward(); // This is STILL invoked when someCondition is true!
}
This is thus actually not true. They do certainly not behave differently than any other Java methods (expect of System#exit() of course). When the someCondition in above example is true and you're thus calling forward() after sendRedirect() or sendError() on the same request/response, then the chance is big that you will get the exception:
java.lang.IllegalStateException: Cannot forward after response has been committed
If the if statement calls a forward() and you're afterwards calling sendRedirect() or sendError(), then below exception will be thrown:
java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
To fix this, you need either to add a return; statement afterwards
protected void doXxx() {
if (someCondition) {
sendRedirect();
return;
}
forward();
}
... or to introduce an else block.
protected void doXxx() {
if (someCondition) {
sendRedirect();
}
else {
forward();
}
}
To naildown the root cause in your code, just search for any line which calls a forward(), sendRedirect() or sendError() without exiting the method block or skipping the remnant of the code. This can be inside the same servlet before the particular code line, but also in any servlet or filter which was been called before the particular servlet.
In case of sendError(), if your sole purpose is to set the response status, use setStatus() instead.
Do not write any string before forward/sendRedirect/sendError
Another probable cause is that the servlet writes to the response while a forward() will be called, or has been called in the very same method.
protected void doXxx() {
out.write("<p>some html</p>");
// ...
forward(); // Fail!
}
The response buffer size defaults in most server to 2KB, so if you write more than 2KB to it, then it will be committed and forward() will fail the same way:
java.lang.IllegalStateException: Cannot forward after response has been committed
Solution is obvious, just don't write to the response in the servlet. That's the responsibility of the JSP. You just set a request attribute like so request.setAttribute("data", "some string") and then print it in JSP like so ${data}. See also our Servlets wiki page to learn how to use Servlets the right way.
Do not write any file before forward/sendRedirect/sendError
Another probable cause is that the servlet writes a file download to the response after which e.g. a forward() is called.
protected void doXxx() {
out.write(bytes);
// ...
forward(); // Fail!
}
This is technically not possible. You need to remove the forward() call. The enduser will stay on the currently opened page. If you actually intend to change the page after a file download, then you need to move the file download logic to page load of the target page. Basically: first create a temporary file on disk using the way mentioned in this answer How to save generated file temporarily in servlet based web application, then send a redirect with the file name/identifier as request param, and in the target page conditionally print based on the presence of that request param a <script>window.location='...';</script> which immediately downloads the temporary file via one of the ways mentioned in this answer Simplest way to serve static data from outside the application server in a Java web application.
Do not call forward/sendRedirect/sendError in JSP
Yet another probable cause is that the forward(), sendRedirect() or sendError() methods are invoked via Java code embedded in a JSP file in form of old fashioned way <% scriptlets %>, a practice which was officially discouraged since 2003. For example:
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
...
<% sendRedirect(); %>
...
</body>
</html>
The problem here is that JSP internally immediately writes template text (i.e. HTML code) via out.write("<!DOCTYPE html> ... etc ...") as soon as it's encountered. This is thus essentially the same problem as explained in previous section.
Solution is obvious, just don't write Java code in a JSP file. That's the responsibility of a normal Java class such as a Servlet or a Filter. See also our Servlets wiki page to learn how to use Servlets the right way.
See also:
What exactly does "Response already committed" mean? How to handle exceptions then?
Unrelated to your concrete problem, your JDBC code is leaking resources. Fix that as well. For hints, see also How often should Connection, Statement and ResultSet be closed in JDBC?
even adding a return statement brings up this exception, for which only solution is this code:
if(!response.isCommitted())
// Place another redirection
Typically you see this error after you have already done a redirect and then try to output some more data to the output stream. In the cases where I have seen this in the past, it is often one of the filters that is trying to redirect the page, and then still forwards through to the servlet. I cannot see anything immediately wrong with the servlet, so you might want to try having a look at any filters that you have in place as well.
Edit: Some more help in diagnosing the problem…
The first step to diagnosing this problem is to ascertain exactly where the exception is being thrown. We are assuming that it is being thrown by the line
getServletConfig().getServletContext()
.getRequestDispatcher("/GroupCopiedUpdt.jsp")
.forward(request, response);
But you might find that it is being thrown later in the code, where you are trying to output to the output stream after you have tried to do the forward. If it is coming from the above line, then it means that somewhere before this line you have either:
output data to the output stream, or
done another redirect beforehand.
Good luck!
You should add return statement while you are forwarding or redirecting the flow.
Example:
if forwardind,
request.getRequestDispatcher("/abs.jsp").forward(request, response);
return;
if redirecting,
response.sendRedirect(roundTripURI);
return;
This is because your servlet is trying to access a request object which is no more exist..
A servlet's forward or include statement does not stop execution of method block. It continues to the end of method block or first return statement just like any other java method.
The best way to resolve this problem just set the page (where you suppose to forward the request) dynamically according your logic. That is:
protected void doPost(request , response){
String returnPage="default.jsp";
if(condition1){
returnPage="page1.jsp";
}
if(condition2){
returnPage="page2.jsp";
}
request.getRequestDispatcher(returnPage).forward(request,response); //at last line
}
and do the forward only once at last line...
you can also fix this problem using return statement after each forward() or put each forward() in if...else block
I removed
super.service(req, res);
Then it worked fine for me
Bump...
I just had the same error. I noticed that I was invoking super.doPost(request, response); when overriding the doPost() method as well as explicitly invoking the superclass constructor
public ScheduleServlet() {
super();
// TODO Auto-generated constructor stub
}
As soon as I commented out the super.doPost(request, response); from within doPost() statement it worked perfectly...
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//super.doPost(request, response);
// More code here...
}
Needless to say, I need to re-read on super() best practices :p
After return forward method you can simply do this:
return null;
It will break the current scope.
If you see this on a Spring based web application, make sure you have your method annotated with #ResponseBody or the controller annotated with #RestController instead of #Controller. It will also throw this exception if a method returns JSON, but has not been configured to have that as the response, Spring will instead look for a jsp page to render and throw this exception.

Resources