Testing a page that requires a logged in user

For example, the page below checks if a user has logged by querying the session:

<html>
Hello: <span wicket:id="name" id="name">John</span>.
</html>

public class PageRequiringLogin extends WebPage {

        public PageRequiringLogin() {
                MySession session = (MySession) WebSession.get();
                String currentUser = session.getCurrentUser();
                if (currentUser == null) {
                        throw new RestartResponseAtInterceptPageException(LoginPage.class);
                }
                add(new Label("name", currentUser));
        }

}

You'd like your test code to simulate both cases: a user has logged and no one has logged in. To simulate the former, let the session ask the application to see if there is a mocked user before really looking for a real user:

public class MySession extends WebSession {
        private String currentUser;
        ...
        public String getCurrentUser() {
                MyApp app = (MyApp) WebApplication.get();
                String mockedUser = app.getMockedUser();
                if (mockedUser != null) {
                        return mockedUser;
                }
                return currentUser;
        }
}

Then your test case can get access to the application and then put a mocked user there:

@Test
public class PageRequiringLoginTest {
        @BeforeMethod
        public void mockLogin() {
                MyApp app = (MyApp) WebPageTestContext.getWebApplication();
                app.setMockedUser("u1");
        }

        @AfterMethod
        public void mockLogout() {
                MyApp app = (MyApp) WebPageTestContext.getWebApplication();
                app.setMockedUser(null);
        }

        public void testAlreadyLoggedIn() {
                DefaultSelenium selenium = WebPageTestContext.getSelenium();
                WicketSelenium ws = new WicketSelenium(selenium);
                ws.openBookmarkablePage(PageRequiringLogin.class);
                assert selenium.isTextPresent("u1");
        }
}

To test a case where the user hasn't logged in (so a login page is displayed), just call mockLogout() first:

@Test
public class PageRequiringLoginTest {
        @BeforeMethod
        public void mockLogin() {
                ...
        }

        @AfterMethod
        public void mockLogout() {
                ...
        }
        public void testNeedToLogIn() {
                mockLogout();
                DefaultSelenium selenium = WebPageTestContext.getSelenium();
                WicketSelenium ws = new WicketSelenium(selenium);
                ws.openBookmarkablePage(PageRequiringLogin.class);
                assert selenium.isTextPresent("Please login");
        }
}

Testing a palette

For example, the page below contains a palette component to let the user choose which products to delete:

<html>
<body>
        <form wicket:id="f">
                <span wicket:id="palette"/>
                <input type="submit" value="OK">
        </form>
</body> 
</html>

public class PalettePage extends WebPage {
        @SpringBean
        private ProductService ps;
        private List<Product> selectedProducts;

        @SuppressWarnings("unchecked")
        public PalettePage() {
                Form<Void> f = new Form<Void>("f") {
                        private static final long serialVersionUID = 1L;

                        @Override
                        protected void onSubmit() {
                                for (Product p : selectedProducts) {
                                        ps.delete(p);
                                }
                        }
                };
                add(f);
                selectedProducts = new ArrayList<Product>();
                List<Product> availableProducts = ps.getAll();
                Palette<Product> palette = new Palette<Product>("palette", new Model(
                                (Serializable) selectedProducts), new Model(
                                (Serializable) availableProducts), new ChoiceRenderer<Product>(
                                "name", "id"), 3, true);
                f.add(palette);
        }
}

To test it, as usual, you will mock the service to provide the list of products and to check the product(s) deleted. See the code below to see how to select an option (a product), how to click the add button and how to inspect the options listed in the two <select> elements:

@Test
public class PalettePageTest {
        private Product deleted;

        public void testPalette() {
                MockableSpringBeanInjector.mockBean("ps", new ProductService() {

                        public List<Product> getAll() {
                                List<Product> products = new ArrayList<Product>();
                                products.add(new Product(0L, "ball pen"));
                                products.add(new Product(1L, "eraser"));
                                products.add(new Product(2L, "paper clip"));
                                return products;
                        }

                        public void delete(Product p) {
                                deleted = p;
                        }

                        public void add(Product p) {
                        }
                });
                WicketSeleniumDriver ws = WebPageTestContext.getWicketSelenium();
                ws.openBookmarkablePage(PalettePage.class);
                Select leftSelect = new Select(ws.findWicketElement("//choices"));
                List<WebElement> allProducts = leftSelect.getOptions();
                assert allProducts.size() == 3;
                assert allProducts.get(0).getText().equals("ball pen");
                assert allProducts.get(1).getText().equals("eraser");
                assert allProducts.get(2).getText().equals("paper clip");
                leftSelect.selectByVisibleText("eraser");
                ws.click("//addButton");
                leftSelect = new Select(ws.findWicketElement("//choices"));
                allProducts = leftSelect.getOptions();
                assert allProducts.size() == 2;
                assert allProducts.get(0).getText().equals("ball pen");
                assert allProducts.get(1).getText().equals("paper clip");
                Select rightSelect = new Select(ws.findWicketElement("//selection"));
                List<WebElement> selectedProducts = rightSelect.getOptions();
                assert selectedProducts.size() == 1;
                assert selectedProducts.get(0).getText().equals("eraser");
                ws.click(By.xpath("//input[@value='OK']"));
                assert deleted.getId() == 1L;
                assert deleted.getName().equals("eraser");
        }

}