3

I'm writing selenium tests for an app that has very standard pages that can easily be modeled by a generic structure as the base for the pages, with only a few base types (mostly list pages containing a list of records, and edit pages where one can edit one record). To model this I have these two classes:

public abstract class AbstractListPage<E extends EditPage> extends AbstractSelfOpeningPage implements ListPage {

    // Provides the specific object for the edit page when it's opened
    protected abstract E editPageHook();

    public E getEditPage() {

        return editPageHook();
    }

    public E openEditPage(String key, boolean search) {

        //Do page opening stuff like clicking buttons

        // Return new object for the page that has been opened
        return getEditPage();
    }
}

// Implementation class
public class DossiersListPage extends AbstractListPage<DossierPage> {

    @Override
    protected DossierPage<DossiersListPage> editPageHook() {

        return new DossierPage<>(driver, this);
    }
}

// Usage in test, this shows an unchecked cast warning
DossierPage<DossiersListPage> dossierPage = new DossiersListPage(driver).openPage().openEditPage("3905");

I would like to know if there is a good way to fix this, and what am I missing? I'm not having any issues currently, but the warning all over my test code is making me feel a bit iffy.

The reason for the generics here is so I can model elements on my page that return the page they belong to in a fluent way:

public abstract class AbstractPageElement<P extends Page> implements PageElement<P> {

    @Override
    public P click() throws TimeoutException {
        // Do click
        return page;
    }
}

// DossierPage
public class DossierPage<L extends ListPage> extends AbstractEditPage<L> {

    public OrderDate<DossierPage<L>> orderDate = new OrderDate<>(driver, this);
    public OrderType<DossierPage<L>> orderType = new OrderType<>(driver, this);
    public Status<DossierPage<L>> status = new Status<>(driver, this);
}

// Test
dossierPage.orderDate.click()
           .orderType.click()
           .status.click();
Mobrockers
  • 2,128
  • 1
  • 16
  • 28
  • DossiersPage is the page with list of dossiers, DossierPage is one single dossier. Perhaps the naming is a bit confusing when you're not used to it. – Mobrockers Jun 21 '16 at 07:59
  • Can you please show how `DossierPage` is declared? I think that will be the tricky part. – Tamas Rev Jun 21 '16 at 11:41
  • I've added the DossierPage class header, do you need anything else? – Mobrockers Jun 21 '16 at 11:46
  • `DossierPage` header is cool, I can go on with it. But then the `DossiersListPage` won't compile the way it is pasted here. I added some suggestions on an answer though. I hope it helps. If not, then please add an sscce http://sscce.org/ so I can take another look. – Tamas Rev Jun 21 '16 at 11:56
  • That's because I extend from my interface and not abstract page in the actual class, but your answer is still correct, so thank you! – Mobrockers Jun 21 '16 at 11:58

2 Answers2

2

I could reverse-engineer the problem. The DossierPage must look something like this:

public class DossierPage<E extends AbstractListPage> extends EditPage {
    //...
}

So now we're getting the problem. You can solve it by specifying more type arguments:

public class DossiersListPage extends
    AbstractListPage<DossierPage<DossiersListPage>> { // this is the tricky part

    @Override
    protected DossierPage<DossiersListPage> editPageHook() {
        return new DossierPage<>();
    }
    //...
}
Mobrockers
  • 2,128
  • 1
  • 16
  • 28
Tamas Rev
  • 7,008
  • 5
  • 32
  • 49
  • Is there a reason you have the same `DossiersListPage` in your code block twice? Cause that seems like a mistake in your answer. – RemcoW Jun 21 '16 at 12:02
-4

Just add the following line above the line giving the warning:

@SuppressWarnings("unchecked")
  • I know I can suppress the warning. I want to find a better way to do what I want. – Mobrockers Jun 21 '16 at 11:15
  • 1
    This isn't a solution. This is sticking your head in the sand like an ostrich and pretend the problem doesn't exist. – RemcoW Jun 21 '16 at 11:26