/******************************************************************************* * Copyright 2017 Ivan Shubin http://galenframework.com * * 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.galenframework.tests.integration; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.galenframework.GalenMain; import com.galenframework.config.GalenConfig; import com.galenframework.config.GalenProperty; import com.galenframework.reports.TestStatistic; import com.google.common.io.Files; import org.apache.commons.io.FileUtils; import org.testng.Assert; import org.testng.annotations.Test; import java.io.File; import java.io.IOException; import java.util.*; import static com.galenframework.tests.integration.RegexBuilder.regex; import static java.util.Arrays.asList; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; public class GalenFullJsProjectIT { public static final String PATH_TO_TEST_PROJECT = GalenFullJsProjectIT.class.getResource("/galen-sample-js-project").getFile(); public static final String PATH_TO_TEST_WEBSITE = "file://" + GalenFullJsProjectIT.class.getResource("/sample-test-website/index.html").getFile(); @Test(enabled = false) public void shouldExecute_completeJsSampleProject() throws Exception { GalenConfig.getConfig().setProperty(GalenProperty.GALEN_USE_FAIL_EXIT_CODE, "false"); GalenConfig.getConfig().setProperty(GalenProperty.GALEN_BROWSER_VIEWPORT_ADJUSTSIZE, "true"); System.setProperty("sample.test.website", PATH_TO_TEST_WEBSITE); System.setProperty("sample.project.path", PATH_TO_TEST_PROJECT); String jsonReportPath = Files.createTempDir().getAbsolutePath() + "/json-report"; String htmlReportPath = Files.createTempDir().getAbsolutePath() + "/html-report"; System.out.println(htmlReportPath); new GalenMain().execute("test", PATH_TO_TEST_PROJECT + "/tests/", "--htmlreport", htmlReportPath, "--jsonreport", jsonReportPath); assertReports(htmlReportPath, jsonReportPath); } private void assertReports(String htmlReportPath, String jsonReportPath) throws IOException { try { ObjectMapper mapper = new ObjectMapper(); JsonNode jsonTree = mapper.readTree(FileUtils.readFileToString(new File(jsonReportPath + "/report.json"))); assertMap(toMap(jsonTree), new HashMap<String, TestStatistic>() {{ put("Add note page on desktop emulation device", new TestStatistic(74, 0, 0, 74)); put("Add note page on mobile emulation device", new TestStatistic(73, 0, 0, 73)); put("Add note page on tablet emulation device", new TestStatistic(74, 0, 0, 74)); put("Login page on desktop emulation device", new TestStatistic(80, 0, 0, 80)); put("Login page on mobile emulation device", new TestStatistic(84, 0, 0, 84)); put("Login page on tablet emulation device", new TestStatistic(79, 0, 0, 79)); put("My notes page on desktop emulation device", new TestStatistic(81, 0, 0, 81)); put("My notes page on mobile emulation device", new TestStatistic(83, 0, 0, 83)); put("My notes page on tablet emulation device", new TestStatistic(81, 0, 0, 81)); put("Welcome page on desktop emulation device", new TestStatistic(70, 1, 0, 71)); put("Welcome page on mobile emulation device", new TestStatistic(68, 0, 0, 68)); put("Welcome page on tablet emulation device", new TestStatistic(70, 1, 0, 71)); }} ); List<String> errorMessages = collectAllErrorMessages(jsonTree, jsonReportPath); assertErrorMessages(errorMessages, asList( regex().exact("\"login_button\" width is ").digits(2).exact("px instead of 20px").toString(), regex().exact("\"login_button\" width is ").digits(2).exact("px instead of 20px").toString() )); } catch (Exception ex) { throw new RuntimeException("Report validation failed:\n" + "Html Report: " + htmlReportPath + "/report.html\n" + "Json Report: " + jsonReportPath + "/report.json", ex); } } private void assertMap(Map<String, TestStatistic> realMap, Map<String, TestStatistic> expectedMap) { assertEquals(realMap.size(), expectedMap.size()); for (Map.Entry<String, TestStatistic> expected : expectedMap.entrySet()) { assertTrue(realMap.containsKey(expected.getKey()), "Should contain: " + expected.getKey()); assertEquals(realMap.get(expected.getKey()), expected.getValue(), "Should have same value for key:" + expected.getKey() + " \nas: " + expected.getValue() + ", but got: " + realMap.get(expected.getKey())); } } private void assertErrorMessages(List<String> errorMessages, List<String> expected) { assertEquals(errorMessages.size(), expected.size()); Iterator<String> expectedIterator = expected.iterator(); int number = 0; for (String errorMessage : errorMessages) { number ++; String pattern = expectedIterator.next(); Assert.assertTrue(errorMessage.matches(pattern), "Error message #" + number + ": " + errorMessage + ",\n should match pattern: " + pattern); } } private List<String> collectAllErrorMessages(JsonNode rootNode, String jsonReportPath) throws IOException { JsonNode testsNode = rootNode.get("tests"); Iterator<JsonNode> it = testsNode.iterator(); List<String> errorMessages = new LinkedList<>(); while(it.hasNext()) { String testId = it.next().get("testId").asText(); errorMessages.addAll(collectAllErrorMessagesFromIndividualTestReport(testId, jsonReportPath)); } return errorMessages; } private List<String> collectAllErrorMessagesFromIndividualTestReport(String testId, String jsonReportPath) throws IOException { ObjectMapper mapper = new ObjectMapper(); JsonNode testReportNode = mapper.readTree(FileUtils.readFileToString(new File(jsonReportPath + "/" + testId + ".json"))); return collectAllErrorMessagesFrom(testReportNode.get("report").get("nodes")); } private List<String> collectAllErrorMessagesFrom(JsonNode jsonNode) { List<String> list = new LinkedList<>(); if (jsonNode.isArray()) { for (JsonNode aJsonNode : jsonNode) { list.addAll(collectAllErrorMessagesFrom(aJsonNode)); } } else { Iterator<String> fieldsIterator = jsonNode.fieldNames(); while(fieldsIterator.hasNext()) { String fieldName = fieldsIterator.next(); if ("errors".equals(fieldName)) { JsonNode errorsNode = jsonNode.get(fieldName); if (errorsNode.isArray()) { for (JsonNode errorNode : errorsNode) { list.add(errorNode.asText()); } } } else { list.addAll(collectAllErrorMessagesFrom(jsonNode.get(fieldName))); } } } return list; } private HashMap<String, TestStatistic> toMap(JsonNode rootNode) { JsonNode testsNode = rootNode.get("tests"); Iterator<JsonNode> it = testsNode.iterator(); HashMap<String, TestStatistic> map = new HashMap<>(); while(it.hasNext()) { JsonNode testNode = it.next(); JsonNode statisticNode = testNode.get("statistic"); map.put(testNode.get("name").asText(), new TestStatistic( statisticNode.get("passed").asInt(), statisticNode.get("errors").asInt(), statisticNode.get("warnings").asInt(), statisticNode.get("total").asInt() )); } return map; } }