From 965c43342187b4cdd67b8dae6290dd3357da3d51 Mon Sep 17 00:00:00 2001 From: James Strachan Date: Fri, 15 Jun 2012 21:09:56 +0100 Subject: [PATCH] add a junit and selenium based test case of the JS compiled version of the kotlin standard ilbrary test cases --- libraries/pom.xml | 1 + .../tools/kotlin-js-tests-junit/ReadMe.md | 7 ++ libraries/tools/kotlin-js-tests-junit/pom.xml | 65 +++++++++++++++ .../kotlin/js/qunit/SeleniumQUnit.kt | 58 +++++++++++++ .../src/test/kotlin/tests/SeleniumTest.java | 82 +++++++++++++++++++ .../test/kotlin/tests/SeleniumTestSuite.kt | 24 ++++++ libraries/tools/kotlin-js-tests/ReadMe.md | 7 ++ 7 files changed, 244 insertions(+) create mode 100644 libraries/tools/kotlin-js-tests-junit/ReadMe.md create mode 100644 libraries/tools/kotlin-js-tests-junit/pom.xml create mode 100644 libraries/tools/kotlin-js-tests-junit/src/main/kotlin/org/jetbrains/kotlin/js/qunit/SeleniumQUnit.kt create mode 100644 libraries/tools/kotlin-js-tests-junit/src/test/kotlin/tests/SeleniumTest.java create mode 100644 libraries/tools/kotlin-js-tests-junit/src/test/kotlin/tests/SeleniumTestSuite.kt create mode 100644 libraries/tools/kotlin-js-tests/ReadMe.md diff --git a/libraries/pom.xml b/libraries/pom.xml index 25f62e38206..70628b11793 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -53,6 +53,7 @@ tools/kotlin-maven-plugin tools/kotlin-js-library tools/kotlin-js-tests + tools/kotlin-js-tests-junit tools/kdoc tools/kdoc-maven-plugin diff --git a/libraries/tools/kotlin-js-tests-junit/ReadMe.md b/libraries/tools/kotlin-js-tests-junit/ReadMe.md new file mode 100644 index 00000000000..f731943f42d --- /dev/null +++ b/libraries/tools/kotlin-js-tests-junit/ReadMe.md @@ -0,0 +1,7 @@ +## Kotlin Standard Library JS Tests JUnit Runner + +This module runs the QUnit JavaScript tests for the Kotlin Standard library inside JUnit using [Selenium WebDriver](http://seleniumhq.org/projects/webdriver/) to run the QUnit code inside any of the drivers available. + +This means we can run the tests automatically in any CI server like TeamCity, Jenkins, Hudson and use any WebDriver provider; such as for FireFox / Chrome / IE etc. + +By default we use the HtmlUnitDriver so it runs using an in memory HTML / JavaScript engine. \ No newline at end of file diff --git a/libraries/tools/kotlin-js-tests-junit/pom.xml b/libraries/tools/kotlin-js-tests-junit/pom.xml new file mode 100644 index 00000000000..537211129b6 --- /dev/null +++ b/libraries/tools/kotlin-js-tests-junit/pom.xml @@ -0,0 +1,65 @@ + + + + 4.0.0 + + + org.jetbrains.kotlin + kotlin-project + 0.1-SNAPSHOT + ../../pom.xml + + + kotlin-js-tests-junit + jar + + + + org.jetbrains.kotlin + kotlin-stdlib + ${project.version} + + + org.seleniumhq.selenium + selenium-java + 2.23.1 + + + org.seleniumhq.selenium + selenium-htmlunit-driver + 2.23.1 + + + + + src/main/kotlin + src/test/kotlin + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${project.version} + + + compile + compile + + compile + + + + + test-compile + test-compile + + test-compile + + + + + + + diff --git a/libraries/tools/kotlin-js-tests-junit/src/main/kotlin/org/jetbrains/kotlin/js/qunit/SeleniumQUnit.kt b/libraries/tools/kotlin-js-tests-junit/src/main/kotlin/org/jetbrains/kotlin/js/qunit/SeleniumQUnit.kt new file mode 100644 index 00000000000..08979b8ce0b --- /dev/null +++ b/libraries/tools/kotlin-js-tests-junit/src/main/kotlin/org/jetbrains/kotlin/js/qunit/SeleniumQUnit.kt @@ -0,0 +1,58 @@ +package org.jetbrains.kotlin.js.qunit + +import java.util.List +import kotlin.test.* +import org.openqa.selenium.By +import org.openqa.selenium.WebDriver +import org.openqa.selenium.WebElement + +/** + * Waits up to a *maxMills* time for a predicate to be true, sleeping for *sleepMillis* + * and retrying until the timeout fails + */ +public fun waitFor(maxMillis: Long, sleepMillis: Long = 100, predicate: () -> Boolean): Boolean { + val end = System.currentTimeMillis() + maxMillis + while (true) { + if (predicate()) { + return true + } + val now = System.currentTimeMillis() + if (now >= end) break + val delta = end - now + val delay = sleepMillis + Thread.sleep(delay) + } + return false +} + +/** + * Helper class to find QUnit tests using Selenium + */ +public class SeleniumQUnit(val driver: WebDriver) { + + /** + * Returns all the test cases found in the current driver's page + */ + public fun findTests(): List { + var resultsElement: WebElement? = null + waitFor(5000) { + resultsElement = driver.findElement(By.id("qunit-tests")) + resultsElement != null + } + assertNotNull(resultsElement, "No qunit test elements could be found in ${driver.getCurrentUrl()}") + return resultsElement!!.findElements(By.tagName("li")).filterNotNull() + } + + public fun findTestName(element: WebElement): String { + return element.getAttribute("id") ?: "unknown test name for $element" + } + + public fun runTest(element: WebElement): Unit { + var result: String = "" + waitFor(5000) { + result = element.getAttribute("class") ?: "no result" + !result.startsWith("run") + } + assertEquals("pass", result, "test result for test case ${findTestName(element)}") + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-js-tests-junit/src/test/kotlin/tests/SeleniumTest.java b/libraries/tools/kotlin-js-tests-junit/src/test/kotlin/tests/SeleniumTest.java new file mode 100644 index 00000000000..16a95c3050a --- /dev/null +++ b/libraries/tools/kotlin-js-tests-junit/src/test/kotlin/tests/SeleniumTest.java @@ -0,0 +1,82 @@ +/** + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 tests; + +import org.jetbrains.kotlin.js.qunit.SeleniumQUnit; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.htmlunit.HtmlUnitDriver; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + */ +@RunWith(Parameterized.class) +public class SeleniumTest { + + protected static WebDriver driver = createDriver(); + + public static HtmlUnitDriver createDriver() { + HtmlUnitDriver answer = new HtmlUnitDriver(true); + answer.setJavascriptEnabled(true); + return answer; + } + + protected static SeleniumQUnit tester = new SeleniumQUnit(driver); + + private final WebElement element; + private String name; + + public SeleniumTest(WebElement element) { + this.element = element; + this.name = tester.findTestName(element); + } + + @Test + public void run() { + tester.runTest(element); + } + + @Override + public String toString() { + return "test " + name; + } + + @Parameterized.Parameters + public static List findTestElements() throws IOException, InterruptedException { + File file = new File("../kotlin-js-tests/src/test/web/index.html"); + driver.get("file://" + file.getCanonicalPath()); + Thread.sleep(500); + List tests = tester.findTests(); + // System.out.println("TESTS are: " + tests); + + List list = new ArrayList(); + for (WebElement test : tests) { + Object[] args = new Object[] { test }; + list.add(args); + } + return list; + } +} diff --git a/libraries/tools/kotlin-js-tests-junit/src/test/kotlin/tests/SeleniumTestSuite.kt b/libraries/tools/kotlin-js-tests-junit/src/test/kotlin/tests/SeleniumTestSuite.kt new file mode 100644 index 00000000000..8557719bcde --- /dev/null +++ b/libraries/tools/kotlin-js-tests-junit/src/test/kotlin/tests/SeleniumTestSuite.kt @@ -0,0 +1,24 @@ +package tests + +import org.junit.* +import org.junit.runners.AllTests +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.junit.runners.Parameterized.Parameters +import java.util.List + +/* +[RunWith(javaClass())] +public class SeleniumTest(val id: String) { + + Test public fun checkQUnitTest(): Unit { + println("Testing $id") + } + + class object { + Parameters public fun findSeleniumUris(): List { + return arrayList("a", "b") + } + } +} +*/ \ No newline at end of file diff --git a/libraries/tools/kotlin-js-tests/ReadMe.md b/libraries/tools/kotlin-js-tests/ReadMe.md new file mode 100644 index 00000000000..55154ae2743 --- /dev/null +++ b/libraries/tools/kotlin-js-tests/ReadMe.md @@ -0,0 +1,7 @@ +## Kotlin Standard Library JS Tests + +This module generates the JavaScript code for a number of JUnit test cases from the stdlib module. + +The tests can then be ran inside any browser by opening the **src/test/web/index.html* file in this directory to run the test cases using [Qunit](http://qunitjs.com/) + +To run the tests in JUnit as part of the maven build, see the **../kotlin-js-tests-runner* module \ No newline at end of file