Selenium NoSuchElementException - java

I am getting the following error.
Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element
(Session info: chrome=39.0.2171.95)
From the looks of the error message it says that it couldnt find such element.
So i added a wait until the element appears.
The funny thing is that the error occurs on the line driver.findElement which means that the wait was able to find the element.
The question is obviously why is selenium not able to find the element.
At first i thought it was because of using a variable in the string
driver.findElement(By.id("_ctl0_ContentPlaceHolder1_eoiSectionSummary_individualRepeater__ctl0_sectionRepeater__ct" + i + "_isCompleteLabel")).getText();
So i tried to store the string somewhere and then findElement with it.
As you see in the code below i have tried using print to verify that the string is the same as the one in the web. And they do match.
Im currently out of ideas now. Please help. Please let me know if you need any other information
public int verifyCompletion() {
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("_ctl0_ContentPlaceHolder1_eoiSectionSummary_individualRepeater__ctl0_sectionRepeater__ctl0_isCompleteLabel")));
int uncompletedCounter = 0;
for (int i = 10; i < 20; i++) {
String text = "_ctl0_ContentPlaceHolder1_eoiSectionSummary_individualRepeater__ctl0_sectionRepeater__ct" + i + "_isCompleteLabel";
driver.findElement(By.id(text)).getText();
System.out.println(text);
boolean sectionCompleted =text.equalsIgnoreCase("Yes");
if (!sectionCompleted) {
uncompletedCounter++;
}
}
return uncompletedCounter;
}

I see a small bug in your selector. You are not parameterizing the selector correctly. I am not sure if it a very efficient way to handle this scenario though.
String selector = "_ctl" + i + "_ContentPlaceHolder1_eoiSectionSummary_individualRepeater__ctl" + i + "_sectionRepeater__ctl" + i + "_isCompleteLabel";
Edit: more precise code should look like this:
public int verifyCompletion() {
int uncompletedCounter = 0;
for (int i = 0; i < 10; i++) {
String selector = "_ctl" + i + "_ContentPlaceHolder1_eoiSectionSummary_individualRepeater__ctl" + i + "_sectionRepeater__ctl" + i + "_isCompleteLabel";
(new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id(selector)));
String elementText = driver.findElement(By.id(selector)).getText();
System.out.println(selector);
System.out.println(elementText);
boolean sectionCompleted =text.equalsIgnoreCase("Yes");
if (!sectionCompleted) {
uncompletedCounter++;
}
}
return uncompletedCounter;
}

Related

Appium is able to see beyond what is displayed on screen

Appium is able to see and find elements that is not displayed on screen
I am trying to build a test automation project, I would like my driver to scroll down
and then perform some operation. but for some reason appium is able to find element even without scrolling down . I am not sure how appium is able to identify element that is not on screen and is only visible to naked eye when you scroll down. Anyone with similar issue found a workaround ?
I am using ExpectedCondition.visibilityOF(element) to determine if element is vsible on screen
public boolean verifyCoverage(String coverage, String value, String type) throws IOException, InterruptedException {
int counter = 0;
for (int i = 0; i < 15; i++) {
AndroidElement element = (AndroidElement) driver.findElementByAndroidUIAutomator("UiSelector().textContains(\"" + coverage + "\")");
//WebElement coverageOption= driver.findElementByXPath("//android.widget.Button[contains(text(),'"+coverage+"')]");
if (AndroidUtilities.waitForVisibility(driver, element)) {
return true;
}
else {
System.out.println ("Cannot see");
return false;
}
}
public static boolean waitForVisibility(AndroidDriver<WebElement> driver, AndroidElement AndroidElement){
try{
// driver.findElementByAndroidUIAutomator("UiSelector().resourceId(\""+targetResourceId+"\")");
WebDriverWait wait = new WebDriverWait(driver, 60);
wait.until(ExpectedConditions.visibilityOf(AndroidElement));
boolean isElementPresent = AndroidElement.isDisplayed();
return isElementPresent;
}catch(Exception e){
boolean isElementPresent = false;
System.out.println(e.getMessage());
return isElementPresent;
}
}
As an answer i would recommend you to use visibilityOfElementLocated instean of visibilityOf.
Plus, if you want to check an element for the existence without getting exceptions, try to take that approach:
if (!((AndroidDriver)driver).findElementsByAndroidUIAutomator("UiSelector().textContains(\"" + coverage + "\")").isEmpty()) {
//some logic when element is located
} else {
//scroll to the particular element
}
You can try these two solution within the page it will able to scroll to the element and do your actions .
MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(\""+element+"\").instance(0))"));
MobileBy.AndroidUIAutomator("new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textMatches(\"" + NumbersCount + "\").instance(0))"));

Java - Pair variable resets between consecutive for loop body executions

This is an excerpt from my project:
import javafx.util.Pair;
import org.w3c.dom.*;
private Pair<Element, Integer> findBestAlbumElement(Element recording) {
Pair<Element, Integer> best = new Pair<>(null, Integer.MIN_VALUE);
NodeList list = recording.getElementsByTagName("release");
for (int i = 0; i < list.getLength(); i++) {
System.out.println((best.getKey() == null ? "null" : best.getKey().getTextContent()) + "; " + best.getValue());
Element album = (Element) list.item(i);
int mark = getAlbumAndYearMark(recording, album);
if (mark > best.getValue()) best = new Pair<>(album, mark);
System.out.println((best.getKey() == null ? "null" : best.getKey().getTextContent()) + "; " + best.getValue());
}
return best;
}
and I'm running into a strange problem in this piece of code. The variable best resets between loop iterations, as seen in the beginning of the printout to console:
null; -2147483648
Live USABootlegAlbumLive1990DE1990GermanyGermanyDE212CD2T.N.T255240; 6
null; -2147483648
...
The first line is the first System.out.println(), the second line is the second one (where the variable best is properly set as expected) and the third line is the first one again (where the variable best seemingly just resets of its own accord).
I've tried to replicate the problem with the following code:
Pair<String, Integer> best = new Pair<>("", Integer.MIN_VALUE);
String[] strings = {"asdf", "fdsa", "dsaf"};
int[] marks = {1, 5, 3};
for (int i = 0; i < strings.length; i++) {
System.out.println(best.getKey() + " " + best.getValue());
if (marks[i] > best.getValue()) best = new Pair<>(strings[i], marks[i]);
System.out.println(best.getKey() + " " + best.getValue());
}
which replaces the NodeList with a String array, but this code works as expected.
My problem is, I don't even know how to approach this issue. I don't know how to debug this further or even reproduce the problem in a smaller example, as I don't know how to create a valid NodeList (since it's an interface, so I can't just new NodeList).
I'm also at a bit of a loss, as it looks to me like the bug appears in a place where it shouldn't even be possible, since the only code that is supposed to execute between the two println calls is i++ (not altering or even accessing best in any way). Am I wrong about this?
Does anyone have any idea what could be going on, or even how I would get closer to pinpointing the issue?
EDIT
As per request, here's getAlbumAndYearMark, which uses the jaudiotagger library (apologies for the ugly long lined code, this is a fairly old project).
private Tag tag;
private int getAlbumAndYearMark(Element recording, Element album) {
int mark = 0;
if (album == null) return tag.hasField(FieldKey.YEAR) ? getYearMark(album) : 0;
if (contains(album.getElementsByTagName("primary-type"), "Album")) mark += 2;
else if (!contains(album.getElementsByTagName("secondary-type"), "Album")) return Integer.MIN_VALUE;
Node title = album.getElementsByTagName("title").item(0);
if (title != null && tag.hasField(FieldKey.ALBUM)) mark += title.getTextContent().equals(tag.getFirst(FieldKey.ALBUM)) ? 7 : -4;
Node date = album.getElementsByTagName("date").item(0);
if (date != null && tag.hasField(FieldKey.YEAR)) mark += date.getTextContent().equals(tag.getFirst(FieldKey.YEAR).trim()) ? 3 : -3;
Node track = album.getElementsByTagName("number").item(0);
if (track != null && tag.hasField(FieldKey.TRACK)) mark += track.getTextContent().equals(tag.getFirst(FieldKey.TRACK).trim()) ? 3 : -1;
return mark;
}
private int getYearMark(Element element) {
NodeList dates = element.getElementsByTagName("date");
for (int i = 0; i < dates.getLength(); i++)
if (dates.item(i).getTextContent().substring(0, 4).equals(tag.getFirst(FieldKey.YEAR))) return 7;
return -7;
}
private static boolean contains(NodeList list, String string) {
for (int i = 0; i < list.getLength(); i++)
if (list.item(i).getTextContent().trim().equalsIgnoreCase(string)) return true;
return false;
}
but I don't believe this method is the problem, as I still have the same issue if I replace int mark = getAlbumYearMark(recording, album); with int mark = (int) (Math.random() * 10);
Here's a (heavily trimmed) example XML file, printed directly from the program:
<?xml version="1.0" encoding="UTF-8"?><metadata xmlns="http://musicbrainz.org/ns/mmd-2.0#" xmlns:ext="http://musicbrainz.org/ns/ext#-2.0" created="2018-02-16T02:07:28.816Z">
<recording-list count="72" offset="0">
<recording ext:score="100" id="6e702972-00c2-4725-b3e5-60e85ef0de25">
<title>T.N.T</title>
<artist-credit>
<name-credit>
<artist id="66c662b6-6e2f-4930-8610-912e24c63ed1">
<name>AC/DC</name>
</artist>
</name-credit>
</artist-credit>
<release-list>
<release id="ddaa5690-df97-4bb2-b93d-396fe5fb49d5">
<title>Live USA</title>
<release-group id="6b1ace64-bf92-3c42-8a1f-aea6fa08edec" type="Live">
<primary-type>Album</primary-type>
<secondary-type-list>
<secondary-type>Live</secondary-type>
</secondary-type-list>
</release-group>
<date>1990</date>
<country>DE</country>
<release-event-list>
<release-event>
<date>1990</date>
<area id="85752fda-13c4-31a3-bee5-0e5cb1f51dad">
<name>Germany</name>
<sort-name>Germany</sort-name>
<iso-3166-1-code-list>
<iso-3166-1-code>DE</iso-3166-1-code>
</iso-3166-1-code-list>
</area>
</release-event>
</release-event-list>
<medium-list>
<track-count>21</track-count>
<medium>
<position>2</position>
<format>CD</format>
<track-list count="11" offset="1">
<track id="caadf3b8-4a44-34c6-b9dc-c9870c5d9bc0">
<number>2</number>
</track>
</track-list>
</medium>
</medium-list>
</release>
</release-list>
</recording>
</recording-list>
</metadata>
You can see an untrimmed example by querying the musicbrainz database directly, for example this query.
It's not an answer (yet). I'm trying with next xml:
<root>
<release-list>
<release id="ddaa5690-df97-4bb2-b93d-396fe5fb49d5">
<title>Live USA</title>
<date>1990</date>
<country>DE</country>
</release>
<release id="qqqa5690-df97-4bb2-b93d-396fe5fb49d5">
<title>German collections</title>
<date>1991</date>
<country>DE</country>
</release>
</release-list>
<release-list>
<release id="zzza5690-df97-4bb2-b93d-396fe5fb49d5">
<title>Just USA</title>
<date>1995</date>
<country>US</country>
</release>
</release-list>
<release-list>
<release id="aaaa5690-df97-4bb2-b93d-396fe5fb49d5">
<title>Anoother USA</title>
<primary-type>Album</primary-type>
<date>1999</date>
<country>RUS</country>
</release>
</release-list>
And I have no issues. Could you please try with this xml?
Also I'm using both incremental mark like return mockMark++; and array-based mark like
private int getAlbumAndYearMark(Element recording, Element album) {
int[] arr = {1,0,5,7,3,6,8,9,10};
return arr[mockMark++];
}

Nested loop creates duplicate entries when ran, cannot find issue?

When the code is ran the nested loop causes it to create occasional duplicate entries to the system, i have spent a while looking through this but still cant find what is causing this, would greatly appreciate any help?
for(int i = 0; i < subWorkItemElement.getChildNodes().getLength(); i++) {
Boolean test = false;
WorkItemCommon existingChild = null;
String summary = null;
if(subWorkItemElement.getChildNodes().item(i).getNodeName().equals("workitem")) {
// We know it's a work item - but is it in the existing list?
Element childWorkItem = (Element) subWorkItemElement.getChildNodes().item(i);
for(int j = 0; j < subWorkItemElement.getChildNodes().getLength(); j++) {
if(childWorkItem.getChildNodes().item(j) instanceof Element) {
if(((Element)childWorkItem.getChildNodes().item(j)).getNodeName().equals("details")) {
summary = ((Element) childWorkItem.getChildNodes().item(j)).getElementsByTagName("summary")
.item(0).getTextContent();
for(String k : userInfoHashMap.keySet()) {
summary = summary.replace("${" + k + "}", userInfoHashMap.get(k));
}
if(childHashTable.containsKey(summary)) {
test = true;
existingChild = childHashTable.get(summary);
IWorkItem workItem = existingChild.getWorkItem();
System.out.println("INFO: The task with summary \"" + summary + "\" already exists. Skipping creation.");
System.out.println("this task is work item: " + workItem.getId());
//either check the tasks in the xml for updated details and then modify the existing workitem
//or just modify the work item without checking for updates
makeChildTask(childWorkItem, existingChild, childHashTable, userInfoHashMap, workItemHashMap, rtc, false);
break;
}
}
}
}
if(!test) {
System.out.println("INFO: The task with summary " + summary + " does not currently exist. Creating.");
makeChildTask(childWorkItem, thisItem, childHashTable, userInfoHashMap, workItemHashMap, rtc, true);
} else makeFromExistingChildTask(childWorkItem, existingChild, userInfoHashMap, workItemHashMap, rtc);
}
}
You are possibly (not sure what makeChildTask() does) changing an XML structure while iterating through the children list. While not necessarily incorrect, this can mean you get entries inserted while you process the list. Since you call the subWorkItemElement.getChildNodes().getLength() each time instead of cache'ing it, this might result in the length changing in between the loop iterations.

How to resolve IndexOutOfBoundsException: Invalid index 1, size is 1? [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 6 years ago.
i've just recived java.lang.IndexOutOfBoundsException: but can't understand what its caused from. Basically, i am integrating records of sqlite table into listview.
Here is my sql query to fetch records from the table.
public ArrayList<Integer> getRecordsCount(int no) {
ArrayList<Integer> count = new ArrayList<>();
Cursor c = database.rawQuery(
"select count(*) as TotalCount, tDate, " +
"strftime('%d', tDate) as DayPart, " +
"strftime('%m', tDate) as MonthPart, " +
"strftime('%Y', tDate) as YearPart " +
"from library " +
"where type = '" + no + "' " +
"group by MonthPart, YearPart", null);
while (c.moveToNext()) {
count.add(c.getInt(0));
}
return count;
}
This is my method to retrieve that data :-
public void setDataInList(int no) {
if (no == 0) {
ArrayList<Integer> count = helper.getRecordsCount(1);
mainGetLibraryModels.clear();
MainLibraryModelWS modelWS = helper.getAllRecordsMonthWise2(no);
for (int i = 0; i < modelWS.getRecords().size(); i++) {
WSLibraryModel model = new WSLibraryModel();
model.setAmount(modelWS.getRecords().get(i).getAmount());
model.setTotalCount("" + count.get(i));
model.setYearPart(modelWS.getRecords().get(i).getYearPart());
model.setMonthPart(modelWS.getRecords().get(i).getMonthPart());
mainGetLibraryModels.add(model);
}
adapter.notifyDataSetChanged();
} else if (no == 1) {
ArrayList<Integer> count = helper.getRecordsCount(2);
mainGetLibraryModels.clear();
MainLibraryModelWS modelWS = helper.getAllRecordsMonthWise2(no);
for (int i = 0; i < modelWS.getRecords().size(); i++) {
WSLibraryModel model = new WSLibraryModel();
model.setAmount(modelWS.getRecords().get(i).getAmount());
model.setTotalCount("" + count.get(i));
model.setYearPart(modelWS.getRecords().get(i).getYearPart());
model.setMonthPart(modelWS.getRecords().get(i).getMonthPart());
mainGetLibraryModels.add(model);
}
adapter.notifyDataSetChanged();
} else {
mainGetLibraryModels.clear();
MainLibraryModelWS modelWS = helper.getAllRecordsMonthWise2(no);
for (int i = 0; i < modelWS.getRecords().size(); i++) {
WSLibraryModel model = new WSLibraryModel();
model.setAmount(modelWS.getRecords().get(i).getAmount());
model.setTotalCount(" - ");
model.setYearPart(modelWS.getRecords().get(i).getYearPart());
model.setMonthPart(modelWS.getRecords().get(i).getMonthPart());
mainGetLibraryModels.add(model);
}
adapter.notifyDataSetChanged();
}
}
But, when i run this code, it gives me this error?
FATAL EXCEPTION: main Process: com.teezom, PID: 14168
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
first of all use switch instead of if-else branching , because what i see your Result from query will give the fix number of result as an array (switch is more efficient and improve readability) .
public void setDataInList(int no) { //just a suggestion not a answer
switch (no){
case 0 :
//Your Code as you specified in your code context.
break;
case 1 :
//Your Code as you specified in your code context.
break;
case 2 :
//Your Code as you specified in your code context.
break;
default :
break;
}
Now Coming to your problem if you see your Exception StackTrace and debug the application once you will get your solution easily.
this is what your stacktrace says--
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
Hope you know this popular exception IndexOutOfBoundsException only came while you try to access the any array index which is not present in array.
Now your error message clearly said that your Array size is one. It means your array will only accessible to index zero (0).
So, Please debug your code and try to find out which line of code is generating exception in-fact
Instead of this :
ArrayList<Integer> count = helper.getRecordsCount(1);
Try this :
ArrayList<Integer> count = helper.getRecordsCount(0);
First, you need to avoid calling getRecords() so many times. It costs performance and might not be returning the same result - the possible reason for your error. Instead, introduce a local parameter as a cache output of this function and play with it.

I am getting error 500 and null pointer exception

I am making project on online examination in java.
I am facing a problem.
On starting base I have 15 questions in my database and I am fetching those sequentially.
The problem is that if I attempt all the answers I get the results otherwise I get error 500 and NullPointerException. The questions are multiple choice. Every question has four options. If I don't attempt all the questions then I get the above error.
<%#page import="java.sql.*"%>
<%
String st[] = new String[20];
String ans[] = new String[20];
int k=0;
//int length = Integer.parseInt(request.getAttribute("length").toString());
for (int i = 0; i < 15; i++)
{
int j = i + 1;
st[i] = request.getParameter("radio" + j);
System.out.println(st[i]);
}
Class.forName("oracle.jdbc.OracleDriver");
Connection connection = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe", "root", "root");
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("Select ANS from ANSWERS order by ID");
//String ans = "";
int t;
while (rs.next()) {
ans[k] = rs.getString("ans");
k++;
System.out.println(ans[k]);
}
int count = 0;
//String answers[] = ans.split(" ");
for (int i = 0; i < 15; i++) {
if (st[i].equals(ans[i])) {
count++;
}
}
out.println("Your " + count + " answers are correct");
%>
At the start of your code you're initializing your st[] with request.getParameter("radio" + j); This might come as null. As per the javadoc for getParameter():
Returns the value of a request parameter as a String, or null if the
parameter does not exist.
So when you try to execute this following piece of code:
for (int i = 0; i < 15; i++) {
if (st[i].equals(ans[i])) {
count++;
}
}
There is a chance that st[i] is in fact null. This might possibly be a reason for the NullPointerException in your code
You should be enclosing your logic in try catch and in finally handle the SQL exception for connection, rs (in separate try catch blocks)
Also, try lloking at the stack trace, as to which line gives the null pointer exception
I would say that your answers are simply not submitted back with your request. If the radio group for a question does not have a selected value, that radio group is not going to be part of the POST request that you are processing after the form submission.
That is why you get the Null pointer exception in the first place.
I cannot runt your example above, but i assume that the error is happening in the comparison line at the end of your example:
if (st[i].equals(ans[i])) {
Update
For a quick fix, just switch the evaluated values: st[i].equals(ans[i]) to ans[i].equals(st[i]). That way you can always do a equals against null and get the correct count.

Categories

Resources