/** * Copyright (C) 2015 Orange * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.francetelecom.clara.cloud.presentation.utils; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.wicket.Component; import org.apache.wicket.MarkupContainer; import org.apache.wicket.protocol.http.WebApplication; import org.apache.wicket.util.lang.Classes; import org.apache.wicket.util.tester.Result; import org.apache.wicket.util.tester.WicketTester; import org.apache.wicket.util.visit.IVisit; import org.apache.wicket.util.visit.IVisitor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * WicketTester use by ElPaaso Wicket test suite. * * This tester allow test developers to reference a component from a part of global path instead of absolute path. * ex : tester.getComponentFromLastRenderedPage("id") * * This mecanism does'nt work with FormTester, you will need to specify all relative path to act on component form * ex : formTester.select("relative:path:to:component:id",true); * * User: wwnl9733 * Date: 13/01/12 * Time: 10:16 * To change this template use File | Settings | File Templates. */ public class PaasWicketTester extends WicketTester { private static final Logger logger = LoggerFactory.getLogger(PaasWicketTester.class.getName()); public PaasWicketTester(WebApplication webApplication) { super(webApplication); } public PaasTestApplication getPaasApplication() { return (PaasTestApplication) this.getApplication(); } @Override public Component getComponentFromLastRenderedPage(final String path) { // first check if we can find the component with the specified path - if not, check if its an abbreviated path String fullPath = lookupPath(getLastRenderedPage(), path); if (fullPath == null) return null; return super.getComponentFromLastRenderedPage(fullPath); } /* this method is overriden because in it's native version it doesn't use getComponentFromLastRenderedPage */ @Override public Result isVisible(String path) { String fullPath = lookupPath(getLastRenderedPage(), path); if (fullPath == null) return null; return super.isVisible(fullPath); } /* Lookup for a Component from its id or its full path */ public String lookupPath(final MarkupContainer markupContainer, final String path) { // try to look it up directly if (markupContainer.get(path) != null) return path; // if that fails, traverse the component hierarchy looking for it final List<Component> candidates = new ArrayList<Component>(); markupContainer.visitChildren(new IVisitor<Component, List<Component>>() { Set<Component> visited = new HashSet<Component>(); @Override public void component(Component c, IVisit<List<Component>> visit) { if (!visited.contains(c)) { visited.add(c); if (c.getId().equals(path)){ candidates.add(c); }else{ if( c.getPath().endsWith(path)){ candidates.add(c); } } } } }); // if its unambiguous, then return the full path if (candidates.isEmpty()) { fail("path: '" + path + "' not found for " + Classes.simpleName(markupContainer.getClass())); return null; } else if (candidates.size() == 1) { String pathToContainer = markupContainer.getPath(); String pathToComponent = candidates.get(0).getPath(); return pathToComponent.replaceFirst(pathToContainer + ":", ""); } else { String message = "path: '" + path + "' is ambiguous for " + Classes.simpleName(markupContainer.getClass()) + ". Possible candidates are: "; for (Component c : candidates) { message += "[" + c.getPath() + "]"; } fail(message); return null; } } public Logger getLogger() { return logger; } }