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-plugintools/kotlin-js-librarytools/kotlin-js-tests
+ tools/kotlin-js-tests-junittools/kdoctools/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