From ba6c505b956c05a59c812e7547261c4a07583505 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Wed, 28 Jul 2021 18:37:19 +0000 Subject: [PATCH 01/10] Add chrome to CI matrix --- .github/workflows/ci.yml | 14 +++++++++++++- build.sbt | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b5523c5fa..0e34dfc7fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: - adopt@1.11 - adopt@1.16 - graalvm-ce-java8@21.1 - ci: [ciJVM, ciJS, ciFirefox] + ci: [ciJVM, ciJS, ciFirefox, ciChrome] exclude: - ci: ciJS java: adopt@1.11 @@ -54,6 +54,18 @@ jobs: scala: 2.12.14 - os: windows-latest ci: ciFirefox + - ci: ciChrome + java: adopt@1.11 + - ci: ciChrome + java: adopt@1.16 + - ci: ciChrome + java: graalvm-ce-java8@21.1 + - os: windows-latest + scala: 3.0.1 + - os: windows-latest + scala: 2.12.14 + - os: windows-latest + ci: ciChrome - java: adopt@1.16 os: windows-latest runs-on: ${{ matrix.os }} diff --git a/build.sbt b/build.sbt index 9bae41e05e..32b7c1378e 100644 --- a/build.sbt +++ b/build.sbt @@ -1,3 +1,4 @@ +import org.openqa.selenium.remote.server.DriverFactory /* * Copyright 2020-2021 Typelevel * @@ -15,8 +16,13 @@ */ import java.io.File +import java.util.concurrent.TimeUnit import com.typesafe.tools.mima.core._ +import org.openqa.selenium.WebDriver +import org.openqa.selenium.remote.server.DriverProvider +import org.openqa.selenium.chrome.ChromeDriver +import org.openqa.selenium.chrome.ChromeOptions import org.openqa.selenium.firefox.FirefoxOptions import org.scalajs.jsenv.selenium.SeleniumJSEnv @@ -96,7 +102,8 @@ ThisBuild / githubWorkflowBuild := Seq( ) ) -val ciVariants = List("ciJVM", "ciJS", "ciFirefox") +val ciVariants = List("ciJVM", "ciJS", "ciFirefox", "ciChrome") +val jsCiVariants = ciVariants.tail ThisBuild / githubWorkflowBuildMatrixAdditions += "ci" -> ciVariants ThisBuild / githubWorkflowBuildMatrixExclusions ++= { @@ -105,7 +112,7 @@ ThisBuild / githubWorkflowBuildMatrixExclusions ++= { MatrixExclude(Map("os" -> Windows, "scala" -> scala)) } - Seq("ciJS", "ciFirefox").flatMap { ci => + jsCiVariants.flatMap { ci => val javaFilters = (ThisBuild / githubWorkflowJavaVersions).value.filterNot(Set(ScalaJSJava)).map { java => MatrixExclude(Map("ci" -> ci, "java" -> java)) @@ -124,14 +131,32 @@ lazy val unidoc213 = taskKey[Seq[File]]("Run unidoc but only on Scala 2.13") lazy val useFirefoxEnv = settingKey[Boolean]("Use headless Firefox (via geckodriver) for running tests") Global / useFirefoxEnv := false +lazy val useChromeEnv = + settingKey[Boolean]("Use headless Chrome (via geckodriver) for running tests") +Global / useChromeEnv := false ThisBuild / Test / jsEnv := { val old = (Test / jsEnv).value if (useFirefoxEnv.value) { val options = new FirefoxOptions() - options.addArguments("-headless") + options.setHeadless(true) new SeleniumJSEnv(options) + } else if (useChromeEnv.value) { + val options = new ChromeOptions() + options.setHeadless(true) + val factory = new DriverFactory { + val defaultFactory = SeleniumJSEnv.Config().driverFactory + def newInstance(capabilities: org.openqa.selenium.Capabilities): WebDriver = { + val driver = defaultFactory.newInstance(capabilities).asInstanceOf[ChromeDriver] + driver.manage().timeouts().pageLoadTimeout(1, TimeUnit.HOURS) + driver.manage().timeouts().setScriptTimeout(1, TimeUnit.HOURS) + driver + } + def registerDriverProvider(provider: DriverProvider): Unit = + defaultFactory.registerDriverProvider(provider) + } + new SeleniumJSEnv(options, SeleniumJSEnv.Config().withDriverFactory(factory)) } else { old } @@ -164,11 +189,15 @@ addCommandAlias( "; project rootJVM; headerCheck; scalafmtCheck; clean; test; mimaReportBinaryIssues; root/unidoc213") addCommandAlias("ciJS", "; project rootJS; headerCheck; scalafmtCheck; clean; test") -// we do the firefox ci *only* on core because we're only really interested in IO here +// we do the browser ci *only* on core because we're only really interested in IO here addCommandAlias( "ciFirefox", "; set Global / useFirefoxEnv := true; project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; set Global / useFirefoxEnv := false" ) +addCommandAlias( + "ciChrome", + "; set Global / useChromeEnv := true; project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; set Global / useChromeEnv := false" +) addCommandAlias("prePR", "; root/clean; scalafmtSbt; +root/scalafmtAll; +root/headerCreate") From 468bd7eb22b053b3fb1537b147b5213b54846454 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Wed, 28 Jul 2021 19:17:50 +0000 Subject: [PATCH 02/10] Bike-shedding a browser setting --- build.sbt | 47 +++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/build.sbt b/build.sbt index 32b7c1378e..42dc933104 100644 --- a/build.sbt +++ b/build.sbt @@ -128,24 +128,23 @@ ThisBuild / githubWorkflowBuildMatrixExclusions ++= Seq( lazy val unidoc213 = taskKey[Seq[File]]("Run unidoc but only on Scala 2.13") -lazy val useFirefoxEnv = - settingKey[Boolean]("Use headless Firefox (via geckodriver) for running tests") -Global / useFirefoxEnv := false -lazy val useChromeEnv = - settingKey[Boolean]("Use headless Chrome (via geckodriver) for running tests") -Global / useChromeEnv := false +lazy val useBrowserEnv = + settingKey[Option[String]]("Use headless browser (via geckodriver) for running tests") +Global / useBrowserEnv := None ThisBuild / Test / jsEnv := { val old = (Test / jsEnv).value - if (useFirefoxEnv.value) { - val options = new FirefoxOptions() - options.setHeadless(true) - new SeleniumJSEnv(options) - } else if (useChromeEnv.value) { - val options = new ChromeOptions() - options.setHeadless(true) - val factory = new DriverFactory { + useBrowserEnv.value.map(_.toLowerCase) match { + case None => old + case Some("firefox") => + val options = new FirefoxOptions() + options.setHeadless(true) + new SeleniumJSEnv(options) + case Some("chrome") => + val options = new ChromeOptions() + options.setHeadless(true) + val factory = new DriverFactory { val defaultFactory = SeleniumJSEnv.Config().driverFactory def newInstance(capabilities: org.openqa.selenium.Capabilities): WebDriver = { val driver = defaultFactory.newInstance(capabilities).asInstanceOf[ChromeDriver] @@ -155,10 +154,10 @@ ThisBuild / Test / jsEnv := { } def registerDriverProvider(provider: DriverProvider): Unit = defaultFactory.registerDriverProvider(provider) - } - new SeleniumJSEnv(options, SeleniumJSEnv.Config().withDriverFactory(factory)) - } else { - old + } + new SeleniumJSEnv(options, SeleniumJSEnv.Config().withDriverFactory(factory)) + case Some(unknown) => + throw new IllegalArgumentException(s"Unrecognized browser env: $unknown") } } @@ -190,14 +189,10 @@ addCommandAlias( addCommandAlias("ciJS", "; project rootJS; headerCheck; scalafmtCheck; clean; test") // we do the browser ci *only* on core because we're only really interested in IO here -addCommandAlias( - "ciFirefox", - "; set Global / useFirefoxEnv := true; project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; set Global / useFirefoxEnv := false" -) -addCommandAlias( - "ciChrome", - "; set Global / useChromeEnv := true; project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; set Global / useChromeEnv := false" -) +def browserCiCommand(browser: String) = + s"""; set Global / useBrowserEnv := Some("$browser"); project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; set Global / useBrowserEnv := None""" +addCommandAlias("ciFirefox", browserCiCommand("firefox")) +addCommandAlias("ciChrome", browserCiCommand("chrome")) addCommandAlias("prePR", "; root/clean; scalafmtSbt; +root/scalafmtAll; +root/headerCreate") From a3818b2eb7f1c9c19d97f08be3d3cc922651f838 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Wed, 28 Jul 2021 19:24:09 +0000 Subject: [PATCH 03/10] Poke CI From edc74eb647a6229ff00dcf7c38e5eff94f0fa734 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Wed, 28 Jul 2021 19:27:15 +0000 Subject: [PATCH 04/10] Poke CI From f1b10267debef7d41826968360188dccc011c2e2 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Thu, 29 Jul 2021 16:34:51 +0000 Subject: [PATCH 05/10] Address the easy comments --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 42dc933104..ebc313ff8c 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,3 @@ -import org.openqa.selenium.remote.server.DriverFactory /* * Copyright 2020-2021 Typelevel * @@ -20,6 +19,7 @@ import java.util.concurrent.TimeUnit import com.typesafe.tools.mima.core._ import org.openqa.selenium.WebDriver +`import org.openqa.selenium.remote.server.DriverFactory import org.openqa.selenium.remote.server.DriverProvider import org.openqa.selenium.chrome.ChromeDriver import org.openqa.selenium.chrome.ChromeOptions @@ -129,7 +129,7 @@ ThisBuild / githubWorkflowBuildMatrixExclusions ++= Seq( lazy val unidoc213 = taskKey[Seq[File]]("Run unidoc but only on Scala 2.13") lazy val useBrowserEnv = - settingKey[Option[String]]("Use headless browser (via geckodriver) for running tests") + settingKey[Option[String]]("Use headless browser for running tests") Global / useBrowserEnv := None ThisBuild / Test / jsEnv := { From 78a4ba2cb858f2f6cd11548da6e8be1e91134e71 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Thu, 29 Jul 2021 17:14:07 +0000 Subject: [PATCH 06/10] Create JSEnv --- build.sbt | 28 ++++++++++++++-------------- project/JSEnv.scala | 6 ++++++ 2 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 project/JSEnv.scala diff --git a/build.sbt b/build.sbt index ebc313ff8c..e8b0b6d0cc 100644 --- a/build.sbt +++ b/build.sbt @@ -19,13 +19,15 @@ import java.util.concurrent.TimeUnit import com.typesafe.tools.mima.core._ import org.openqa.selenium.WebDriver -`import org.openqa.selenium.remote.server.DriverFactory +import org.openqa.selenium.remote.server.DriverFactory import org.openqa.selenium.remote.server.DriverProvider import org.openqa.selenium.chrome.ChromeDriver import org.openqa.selenium.chrome.ChromeOptions import org.openqa.selenium.firefox.FirefoxOptions import org.scalajs.jsenv.selenium.SeleniumJSEnv +import JSEnv._ + ThisBuild / baseVersion := "3.1" ThisBuild / organization := "org.typelevel" @@ -128,20 +130,20 @@ ThisBuild / githubWorkflowBuildMatrixExclusions ++= Seq( lazy val unidoc213 = taskKey[Seq[File]]("Run unidoc but only on Scala 2.13") -lazy val useBrowserEnv = - settingKey[Option[String]]("Use headless browser for running tests") -Global / useBrowserEnv := None +lazy val useJSEnv = + settingKey[JSEnv]("Use Node.js or a headless browser for running Scala.js tests") +Global / useJSEnv := NodeJS ThisBuild / Test / jsEnv := { val old = (Test / jsEnv).value - useBrowserEnv.value.map(_.toLowerCase) match { - case None => old - case Some("firefox") => + useJSEnv.value match { + case NodeJS => old + case Firefox => val options = new FirefoxOptions() options.setHeadless(true) new SeleniumJSEnv(options) - case Some("chrome") => + case Chrome => val options = new ChromeOptions() options.setHeadless(true) val factory = new DriverFactory { @@ -156,8 +158,6 @@ ThisBuild / Test / jsEnv := { defaultFactory.registerDriverProvider(provider) } new SeleniumJSEnv(options, SeleniumJSEnv.Config().withDriverFactory(factory)) - case Some(unknown) => - throw new IllegalArgumentException(s"Unrecognized browser env: $unknown") } } @@ -189,10 +189,10 @@ addCommandAlias( addCommandAlias("ciJS", "; project rootJS; headerCheck; scalafmtCheck; clean; test") // we do the browser ci *only* on core because we're only really interested in IO here -def browserCiCommand(browser: String) = - s"""; set Global / useBrowserEnv := Some("$browser"); project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; set Global / useBrowserEnv := None""" -addCommandAlias("ciFirefox", browserCiCommand("firefox")) -addCommandAlias("ciChrome", browserCiCommand("chrome")) +def browserCiCommand(browser: JSEnv) = + s"""; set Global / useJSEnv := JSEnv.$browser; project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; set Global / useJSEnv := NodeJS""" +addCommandAlias("ciFirefox", browserCiCommand(Firefox)) +addCommandAlias("ciChrome", browserCiCommand(Chrome)) addCommandAlias("prePR", "; root/clean; scalafmtSbt; +root/scalafmtAll; +root/headerCreate") diff --git a/project/JSEnv.scala b/project/JSEnv.scala new file mode 100644 index 0000000000..0ec9606cc3 --- /dev/null +++ b/project/JSEnv.scala @@ -0,0 +1,6 @@ +sealed abstract class JSEnv +object JSEnv { + case object Chrome extends JSEnv + case object Firefox extends JSEnv + case object NodeJS extends JSEnv +} From 38177fb38a7575f98bd3bb03ee8ca30cf62463d1 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Thu, 29 Jul 2021 17:23:18 +0000 Subject: [PATCH 07/10] Fix browser ci command --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index e8b0b6d0cc..86cd6d471d 100644 --- a/build.sbt +++ b/build.sbt @@ -190,7 +190,7 @@ addCommandAlias("ciJS", "; project rootJS; headerCheck; scalafmtCheck; clean; te // we do the browser ci *only* on core because we're only really interested in IO here def browserCiCommand(browser: JSEnv) = - s"""; set Global / useJSEnv := JSEnv.$browser; project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; set Global / useJSEnv := NodeJS""" + s"""; set Global / useJSEnv := JSEnv.$browser; project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; set Global / useJSEnv := JSEnv.NodeJS""" addCommandAlias("ciFirefox", browserCiCommand(Firefox)) addCommandAlias("ciChrome", browserCiCommand(Chrome)) From e55220d376c8e754c2f6f03e950bba14aad9473c Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Thu, 29 Jul 2021 17:29:36 +0000 Subject: [PATCH 08/10] Remove extra quotes --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 86cd6d471d..ebe9781a16 100644 --- a/build.sbt +++ b/build.sbt @@ -190,7 +190,7 @@ addCommandAlias("ciJS", "; project rootJS; headerCheck; scalafmtCheck; clean; te // we do the browser ci *only* on core because we're only really interested in IO here def browserCiCommand(browser: JSEnv) = - s"""; set Global / useJSEnv := JSEnv.$browser; project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; set Global / useJSEnv := JSEnv.NodeJS""" + s"; set Global / useJSEnv := JSEnv.$browser; project rootJS; headerCheck; scalafmtCheck; clean; testsJS/test; set Global / useJSEnv := JSEnv.NodeJS" addCommandAlias("ciFirefox", browserCiCommand(Firefox)) addCommandAlias("ciChrome", browserCiCommand(Chrome)) From 3673f6b9c22d3f8456945e0df36589a57160b6b6 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Fri, 30 Jul 2021 05:34:45 +0000 Subject: [PATCH 09/10] Try fixing webworker for chrome --- build.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sbt b/build.sbt index 4fde1bcaaf..38b10bacbf 100644 --- a/build.sbt +++ b/build.sbt @@ -150,6 +150,7 @@ ThisBuild / Test / jsEnv := { case Chrome => val options = new ChromeOptions() options.setHeadless(true) + options.addArguments("--allow-file-access-from-files") val factory = new DriverFactory { val defaultFactory = SeleniumJSEnv.Config().driverFactory def newInstance(capabilities: org.openqa.selenium.Capabilities): WebDriver = { From 1afac138f8cce22ee5aea1c17fa635a88a93aa81 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Fri, 30 Jul 2021 19:25:49 +0000 Subject: [PATCH 10/10] Disable thin client --- .github/workflows/ci.yml | 10 +++++----- build.sbt | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e34dfc7fc..7339656c07 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,22 +105,22 @@ jobs: - name: Check that workflows are up to date shell: bash - run: sbt --client '++${{ matrix.scala }}; githubWorkflowCheck' + run: sbt ++${{ matrix.scala }} githubWorkflowCheck - shell: bash - run: sbt --client '++${{ matrix.scala }}; ${{ matrix.ci }}' + run: sbt ++${{ matrix.scala }} '${{ matrix.ci }}' - if: (matrix.scala == '2.13.6' || matrix.scala == '3.0.1') && matrix.ci == 'ciJVM' shell: bash - run: sbt --client '++${{ matrix.scala }}; docs/mdoc' + run: sbt ++${{ matrix.scala }} docs/mdoc - if: matrix.ci == 'ciJVM' && matrix.os == 'ubuntu-latest' shell: bash - run: sbt --client '++${{ matrix.scala }}; exampleJVM/compile' + run: sbt ++${{ matrix.scala }} exampleJVM/compile - if: matrix.ci == 'ciJS' && matrix.os == 'ubuntu-latest' shell: bash - run: sbt --client '++${{ matrix.scala }}; exampleJS/compile' + run: sbt ++${{ matrix.scala }} exampleJS/compile - name: Test Example JVM App Within Sbt if: matrix.ci == 'ciJVM' && matrix.os == 'ubuntu-latest' diff --git a/build.sbt b/build.sbt index 38b10bacbf..c01b582def 100644 --- a/build.sbt +++ b/build.sbt @@ -59,6 +59,7 @@ val Scala3 = "3.0.1" ThisBuild / crossScalaVersions := Seq(Scala3, "2.12.14", Scala213) +ThisBuild / githubWorkflowUseSbtThinClient := false ThisBuild / githubWorkflowTargetBranches := Seq("series/3.x") val LTSJava = "adopt@1.11"