/*
* Copyright 2000-2016 Vaadin Ltd.
*
* 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.vaadin.tests.htmlimport;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import com.vaadin.testbench.By;
import com.vaadin.testbench.parallel.BrowserUtil;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class HtmlImportUITest extends MultiBrowserTest {
@Override
public List<DesiredCapabilities> getBrowsersToTest() {
List<DesiredCapabilities> browsers = getBrowsersExcludingPhantomJS();
browsers.add(PHANTOMJS2());
return browsers.stream().filter(dc -> {
// Won't work on Firefox 24, will work when testing is done on a
// modern Firefox
if (BrowserUtil.isFirefox(dc) && dc.getVersion().equals("24")) {
return false;
}
return true;
}).collect(Collectors.toList());
}
@Test
public void importsLoadedAfterJs() {
openTestURL();
WebElement log = findElement(By.id("clientlog")); // Defined by ui.js
List<WebElement> messages = log.findElements(By.className("message"));
// Assert.assertEquals("Some log messages are missing or extra", 3,
// messages.size());
// JS before HTML, UI deps in bootstrap, rest dynamically
// ui.js just sets up the logging
Assert.assertEquals("ui.html", messages.get(0).getText());
// Apparently Chrome does not guarantee that "label.js" is executed
// before "label.html", at least in the way we are loading HTML and JS.
// Therefore, this just checks the order of the import statements
List<WebElement> headContents = findElements(By.xpath("//head/*"));
Map<String, Integer> htmlImportIndexes = new HashMap<String, Integer>();
Map<String, Integer> jsIndexes = new HashMap<String, Integer>();
for (int i = 0; i < headContents.size(); i++) {
WebElement e = headContents.get(i);
if (e.getTagName().equalsIgnoreCase("link")
&& e.getAttribute("rel").equalsIgnoreCase("import")) {
// HTML import
String href = e.getAttribute("href");
String file = href.substring(href.lastIndexOf('/') + 1);
Assert.assertFalse("Multiple HTML imports for " + file,
htmlImportIndexes.containsKey(file));
htmlImportIndexes.put(file, i);
} else if (e.getTagName().equalsIgnoreCase("script")) {
// JS
String src = e.getAttribute("src");
String file = src.substring(src.lastIndexOf('/') + 1);
Assert.assertFalse("Multiple script tags for " + file,
jsIndexes.containsKey(file));
jsIndexes.put(file, i);
}
}
// label.* + label2.* are from super + sub class loaded in
// that defined order
// labelX.* are on another component so it can come before or after
int superJsIndex = jsIndexes.get("label.js");
int superHtmlIndex = htmlImportIndexes.get("label.html");
int subJsIndex = jsIndexes.get("label2.js");
int subHtmlIndex = htmlImportIndexes.get("label2.html");
int otherJsIndex = jsIndexes.get("labelX.js");
int otherHtmlIndex = htmlImportIndexes.get("labelX.html");
Assert.assertTrue("super js should be before super html",
superJsIndex < superHtmlIndex);
Assert.assertTrue("super dependencies should be before sub js",
superHtmlIndex < subJsIndex);
Assert.assertTrue("sub js should be before sub html",
subJsIndex < subHtmlIndex);
}
}