I am attempting to fix already written code which deals with getting a grid from a webpage. Currently the code looks like this:
public static Grid getGrid(String gridXpath) {
Grid grid = new Grid();
String html = getWebDriver().findElement(By.xpath(gridXpath)).getAttribute("outerHTML");
Document doc = Jsoup.parse(html);
String paginationType = getPaginationType(gridXpath);
grid.setPaginationType(paginationType);
// get headers
Element table = doc.select("table").get(0);
Elements headers = table.select("th");
table = doc.select("table").get(doc.select("table").size() - 1);
Elements bodies = table.select("tbody");
Elements rows = bodies.select("tr");
Elements detailRows = bodies.select("tr.k-detail-row");
for (Element th : headers) {
if (th.hasClass("k-header") && !th.hasClass("k-hierarchy-cell")) {
if (th.html().contains("class=\"second-row\"")) {
Element subHeader = th.selectFirst("span.second-row");
grid.addSubHeader(subHeader.text());
th.select("span.second-row").remove();
grid.addHeader(th.text());
} else {
grid.addHeader(th.text());
grid.addSubHeader(null);
}
} else if (!th.hasClass("k-hierarchy-cell")) {
grid.addHeader(th.text());
grid.addSubHeader(null);
}
}
// add detail row header if it exists
if (!detailRows.isEmpty()) {
grid.addHeader("detail");
grid.addSubHeader("detail");
}
// get rows
for (Element tr : rows) {
Row row = grid.new Row();
if (tr.hasClass("k-master-row")) {
Elements cells = tr.select("td");
for (Element td : cells) {
Cell cell = grid.new Cell();
cell.addCellLocation(td.cssSelector());
if (td.attr("role").equalsIgnoreCase("gridcell")) {
if (td.html().contains("onclick=")) {
Element button = td.selectFirst("button");
cell.addCellControl(button.cssSelector());
td.select("button").remove();
} else {
cell.addCellControl(null);
}
if (td.html().contains("span")) {
if (td.html().contains("class=\"second-row\"")) {
Element subCell = td.selectFirst("span.second-row");
if (subCell.text().isEmpty()) {
cell.setSubText(null);
} else {
cell.setSubText(subCell.text());
}
td.select("span.second-row").remove();
if (td.text().isEmpty()) {
cell.setText(null);
} else {
cell.setText(td.text());
}
} else {
cell.setText(td.select("span").text());
td.select("span").remove();
cell.setSubText(td.text());
}
} else {
cell.setText(td.text());
cell.setSubText(null);
}
row.addCell(cell);
}
}
row.addCell(createCell(detailRows.get((grid.getRows().size())).cssSelector(), detailRows.get((grid.getRows().size())).text()));
grid.addRow(row);
} else if (!tr.hasClass("k-detail-row")) {
Elements cells = tr.select("td");
for (Element td : cells) {
Cell cell = grid.new Cell();
cell.addCellLocation(td.cssSelector());
if (td.html().contains("<input")) {
Element input = td.selectFirst("input");
cell.setText(null);
cell.setSubText(null);
cell.addCellControl(input.cssSelector());
} else {
cell.setText(td.text());
cell.setSubText(null);
cell.addCellControl(null);
}
row.addCell(cell);
if (td.hasAttr("colspan")) {
for (int i = 1; i < Integer.valueOf(td.attr("colspan")); i++) {
row.addCell(createCell(null, null));
}
}
}
grid.addRow(row);
}
}
This code works fine if there is only one page of data on the grid, but it falls over when there are more than one. To solve this, I have attempted to add some pagination code. I have the following so far:
if (paginationType != null && getCurrentPage(gridXpath, grid.getPaginationType()) != getLastPageNumberShownInPagination(gridXpath, grid.getPaginationType())) {
do {
gotoNextPage(gridXpath, grid.getPaginationType());
html = getWebDriver().findElement(By.xpath(gridXpath)).getAttribute("outerHTML");
doc = Jsoup.parse(html);
table = doc.select("table").get(0);
table = doc.select("table").get(doc.select("table").size() - 1);
bodies = table.select("tbody");
rows = bodies.select("tr");
detailRows = bodies.select("tr.k-detail-row");
for (Element tr : rows) {
Row row = grid.new Row();
if (tr.hasClass("k-master-row")) {
Elements cells = tr.select("td");
for (Element td : cells) {
Cell cell = grid.new Cell();
cell.addCellLocation(td.cssSelector());
if (td.attr("role").equalsIgnoreCase("gridcell")) {
if (td.html().contains("onclick=")) {
Element button = td.selectFirst("button");
cell.addCellControl(button.cssSelector());
td.select("button").remove();
} else {
cell.addCellControl(null);
}
if (td.html().contains("span")) {
if (td.html().contains("class=\"second-row\"")) {
Element subCell = td.selectFirst("span.second-row");
if (subCell.text().isEmpty()) {
cell.setSubText(null);
} else {
cell.setSubText(subCell.text());
}
td.select("span.second-row").remove();
if (td.text().isEmpty()) {
cell.setText(null);
} else {
cell.setText(td.text());
}
} else {
cell.setText(td.select("span").text());
td.select("span").remove();
cell.setSubText(td.text());
}
} else {
cell.setText(td.text());
cell.setSubText(null);
}
row.addCell(cell);
}
}
row.addCell(createCell(detailRows.get((grid.getRows().size())).cssSelector(), detailRows.get((grid.getRows().size())).text()));
grid.addRow(row);
} else if (!tr.hasClass("k-detail-row")) {
Elements cells = tr.select("td");
for (Element td : cells) {
Cell cell = grid.new Cell();
cell.addCellLocation(td.cssSelector());
if (td.html().contains("<input")) {
Element input = td.selectFirst("input");
cell.setText(null);
cell.setSubText(null);
cell.addCellControl(input.cssSelector());
} else {
cell.setText(td.text());
cell.setSubText(null);
cell.addCellControl(null);
}
row.addCell(cell);
if (td.hasAttr("colspan")) {
for (int i = 1; i < Integer.valueOf(td.attr("colspan")); i++) {
row.addCell(createCell(null, null));
}
}
}
grid.addRow(row);
}
}
Most of this code is just a copy/paste from the previous code, but when I run it I am getting the error 'java.lang.IndexOutOfBoundsException: Index 10 out of bounds for length 3' from the following line:
row.addCell(createCell(detailRows.get((grid.getRows().size())).cssSelector(), detailRows.get((grid.getRows().size())).text()));
I am not sure why this line of code works before pagination but doesn't work after. Any help would be greatly appreciated.
EDIT: So it turns out the issue is that the grid contains all data from the previous page, and so when I use grid.getRows().size() it is counting all rows instead of just the rows from the current page. Any suggestions on how I can use just the rows on the current page ?
Can I create a new grid and the add this to the existing grid once I have all the data ?
Please note that the size of the List
is not equal to the actual available List
indexes. For a List
with 2 elements, you would get the size of 2, but the actual elements can be received with list.get(0)
and list.get(1);
.
To fix you problem, simply subtract one from your list size:
detailRows.get((grid.getRows().size() - 1)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.