Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
XWiki Selenium Jupiter Extension
/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.test.docker.junit5;
import java.util.Arrays;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.xwiki.test.integration.XWikiExecutor;
import org.xwiki.test.ui.AbstractTest;
import org.xwiki.test.ui.PersistentTestContext;
import org.xwiki.test.ui.TestUtils;
import org.xwiki.test.ui.XWikiWebDriver;
import io.github.bonigarcia.SeleniumExtension;
/**
* Extends Selenium Jupiter to be able to inject a {@link TestUtils} instance in tests and to start/start XWiki
* automatically.
*
* @version $Id: b8d94a31d883e7789466b1a5ac1eb3baee879573 $
* @since 10.6RC1
*/
public class XWikiDockerExtension extends SeleniumExtension implements BeforeAllCallback, AfterAllCallback
{
private static final ExtensionContext.Namespace NAMESPACE =
ExtensionContext.Namespace.create(XWikiDockerExtension.class);
@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
{
Class<?> type = parameterContext.getParameter().getType();
return super.supportsParameter(parameterContext, extensionContext) || TestUtils.class.isAssignableFrom(type);
}
@Override
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
{
PersistentTestContext testContext = loadPersistentTestContext(extensionContext);
Class<?> type = parameterContext.getParameter().getType();
if (WebDriver.class.isAssignableFrom(type)) {
RemoteWebDriver webDriver = (RemoteWebDriver) super.resolveParameter(parameterContext, extensionContext);
XWikiWebDriver xwikiWebDriver = new XWikiWebDriver(webDriver);
testContext.setDriver(xwikiWebDriver);
return xwikiWebDriver;
} else {
// Provide TestUtils instance to the test as parameter
return testContext.getUtil();
}
}
@Override
public void beforeAll(ExtensionContext extensionContext) throws Exception
{
// Initialize the test context but without the webdriver which will be set when it's resolved in
// resolveParameter().
PersistentTestContext testContext = initializePersistentTestContext();
savePersistentTestContext(extensionContext, testContext);
// Start XWiki
// TODO: in the future, refactor XWikiExecutor so that it becomes an interface and so that we can have
// various implementations, including one using Docker to start/stop XWiki.
for (XWikiExecutor executor : testContext.getExecutors()) {
executor.start();
}
}
@Override
public void afterAll(ExtensionContext extensionContext) throws Exception
{
PersistentTestContext testContext = loadPersistentTestContext(extensionContext);
// Stop XWiki
for (XWikiExecutor executor : testContext.getExecutors()) {
executor.stop();
}
// Shutdown the test context
shutdownPersistentTestContext(testContext);
}
private void savePersistentTestContext(ExtensionContext context, PersistentTestContext testContext)
{
ExtensionContext.Store store = getStore(context);
Class<?> testClass = context.getRequiredTestClass();
store.put(testClass, testContext);
}
private PersistentTestContext loadPersistentTestContext(ExtensionContext context)
{
ExtensionContext.Store store = getStore(context);
Class<?> testClass = context.getRequiredTestClass();
return store.get(testClass, PersistentTestContext.class);
}
private static ExtensionContext.Store getStore(ExtensionContext context)
{
return context.getRoot().getStore(NAMESPACE);
}
private PersistentTestContext initializePersistentTestContext()
{
PersistentTestContext testContext;
try {
testContext = new PersistentTestContext(Arrays.asList(new XWikiExecutor(0)), null);
AbstractTest.initializeSystem(testContext.getUnstoppable());
} catch (Exception e) {
throw new RuntimeException("Failed to initialize PersistentTestContext", e);
}
return testContext;
}
private void shutdownPersistentTestContext(PersistentTestContext testContext)
{
if (testContext != null) {
try {
testContext.shutdown();
} catch (Exception e) {
throw new RuntimeException("Failed to shutdown PersistentTestContext", e);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment