I am describing a grid or table view using Selenium. What I want to do is to develop an abstract class Table from which another classes will inherit. Here is the idea:
AbstractTable class:
public abstract class AbstractTable extends HtmlElement {
public abstract Class<? extends AbstractRow> getHeader();
public abstract Class<? extends AbstractRow> getRow();
private Class<? extends AbstractRow> tableHeader = getHeader();
private Class<? extends AbstractRow> tableRow = getRow();
public AbstractTable() { // init method }
}
AbstractRow class:
@FindBy(xpath = ".//thead/tr")
public abstract class AbstractRow extends HtmlElement {
@Override
public Rectange getRect() { return null; }
}
MyTable class:
class MyTable extends AbstractTable {
@Override
public Class<? extends AbstractRow> getHeader() { return TableHead.class; }
@Override
public Class<? extends AbstractRow> getRow() { return TableRow.class; }
@FindBy(xpath = ".//thead/tr")
public static class TableHead extends AbstractRow { // some fields }
@FindBy(xpath = ".//tbody/tr[not(@class = 'clicked')]")
public static class TableRow extends AbstractRow { // some fields }
}
Imagine that there are more than one class which is similar to MyTable.
So, my main question is: will my inner classes of class MyTable be decorated and initialized? Or, if not, then maybe there is a way to do this more efficient?
I tried to do something similar in the past. However, it was much more simple.
Here is code snippet:
public class Table extends AbstractPageElement {
public Table(WebElement wrappedElement, String name, String page) {
super(wrappedElement, name, page);
}
public static final String ROW_XPATH_LOCATOR = "//tbody/tr";
private static String getCellXpathLocator(int row, int column) {
return ROW_XPATH_LOCATOR + "[" + row + "]/td[" + column + "]";
}
public int getRowCount() {
return findAllByXPath(ROW_XPATH_LOCATOR).size();
}
public String getCellValue(int row, int column) {
Cell cell = new Cell(row, column, this.name, this.page);
return cell.getText();
}
public class Cell extends AbstractPageElement {
private int row;
private int column;
public Cell(WebElement wrappedElement, String name, String page) {
super(wrappedElement, name, page);
}
public Cell(int row, int column, String name, String page) {
super(Table.this.findByXPath(getCellXpathLocator(row, column)), name, page);
this.row = row;
this.column = column;
}
public String getText() {
return wrappedElement.getText();
}
public Cell nextInRow() {
return new Cell(row, column + 1, name, page);
}
public Cell previousInRow() {
return new Cell(row, column - 1, name, page);
}
public Cell nextInColumn() {
return new Cell(row + 1, column, name, page);
}
public Cell previousInColumn() {
return new Cell(row - 1, column, name, page);
}
}
}
AbstractPageElement
was used with default implementation for FieldDecorator
.
Project structure was like:
Also, you can have a look to yandex-qatools htmlelements. They created custom decorator and wrapper classes for elements.
BTW: they have implementation for Table