|
1 | 1 | package jsenv.playwright
|
2 | 2 |
|
| 3 | +import cats.effect.IO |
3 | 4 | import cats.effect.unsafe.implicits.global
|
4 |
| -import cats.effect.{IO, Resource} |
5 |
| -import com.microsoft.playwright.BrowserType.LaunchOptions |
6 | 5 | import jsenv.playwright.PWEnv.Config
|
7 |
| -import jsenv.playwright.PageFactory._ |
8 |
| -import jsenv.playwright.ResourcesFactory._ |
9 |
| -import org.scalajs.jsenv.{Input, JSComRun, JSRun, RunConfig} |
| 6 | +import org.scalajs.jsenv.Input |
| 7 | +import org.scalajs.jsenv.JSRun |
| 8 | +import org.scalajs.jsenv.RunConfig |
10 | 9 |
|
11 |
| -import java.util.concurrent.ConcurrentLinkedQueue |
12 |
| -import java.util.concurrent.atomic.AtomicBoolean |
13 | 10 | import scala.concurrent._
|
14 |
| -import scala.concurrent.duration.DurationInt |
15 | 11 |
|
16 | 12 | class CERun(
|
17 |
| - browserName: String, |
18 |
| - headless: Boolean, |
19 |
| - pwConfig: Config, |
20 |
| - runConfig: RunConfig, |
21 |
| - input: Seq[Input] |
22 |
| -) extends JSRun { |
23 |
| - |
24 |
| - implicit val ec: scala.concurrent.ExecutionContext = |
25 |
| - scala.concurrent.ExecutionContext.global |
26 |
| - |
27 |
| - // enableCom is false for CERun and true for CEComRun |
28 |
| - protected val enableCom = false |
29 |
| - protected val intf = "this.scalajsPlayWrightInternalInterface" |
30 |
| - protected val sendQueue = new ConcurrentLinkedQueue[String] |
31 |
| - // receivedMessage is called only from JSComRun. Hence its implementation is empty in CERun |
32 |
| - protected def receivedMessage(msg: String): Unit = () |
33 |
| - |
34 |
| - /** A Future that completes if the run completes. |
35 |
| - * |
36 |
| - * The future is failed if the run fails. |
37 |
| - * |
38 |
| - * Note that a JSRun is not required to ever terminate on it's own. That |
39 |
| - * means even if all code is executed and the event loop is empty, the run |
40 |
| - * may continue to run. As a consequence, it is *not* correct to rely on |
41 |
| - * termination of a JSRun without any external means of stopping it (i.e. |
42 |
| - * calling [[close]]). |
43 |
| - */ |
44 |
| - var wantToClose = new AtomicBoolean(false) |
45 |
| - // List of programs |
46 |
| - // 1. isInterfaceUp() |
47 |
| - // Create PW resource if not created. Create browser,context and page |
48 |
| - // 2. Sleep |
49 |
| - // 3. wantClose |
50 |
| - // 4. sendAll() |
51 |
| - // 5. fetchAndProcess() |
52 |
| - // 6. Close diver |
53 |
| - // 7. Close streams |
54 |
| - // 8. Close materializer |
55 |
| - // Flow |
56 |
| - // if interface is down and dont want to close wait for 100 milliseconds |
57 |
| - // interface is up and dont want to close sendAll(), fetchAndProcess() Sleep for 100 milliseconds |
58 |
| - // If want to close then close driver, streams, materializer |
59 |
| - // After future is completed close driver, streams, materializer |
60 |
| - |
61 |
| - def jsRunPrg( |
62 |
| - browserName: String, |
63 |
| - headless: Boolean, |
64 |
| - isComEnabled: Boolean, |
65 |
| - launchOptions: Option[LaunchOptions] |
66 |
| - ): Resource[IO, Unit] = for { |
67 |
| - _ <- Resource.pure( |
68 |
| - scribe.info( |
69 |
| - s"Begin Main with isComEnabled $isComEnabled " + |
70 |
| - s"and browserName $browserName " + |
71 |
| - s"and headless is $headless " |
72 |
| - ) |
73 |
| - ) |
74 |
| - pageInstance <- createPage( |
75 |
| - browserName, |
76 |
| - headless, |
77 |
| - launchOptions |
78 |
| - ) |
79 |
| - _ <- preparePageForJsRun( |
80 |
| - pageInstance, |
81 |
| - materializer(pwConfig), |
82 |
| - input, |
83 |
| - isComEnabled |
84 |
| - ) |
85 |
| - connectionReady <- isConnectionUp(pageInstance, intf) |
86 |
| - _ <- |
87 |
| - if (!connectionReady) Resource.pure[IO, Unit](IO.sleep(100.milliseconds)) |
88 |
| - else Resource.pure[IO, Unit](IO.unit) |
89 |
| - _ <- isConnectionUp(pageInstance, intf) |
90 |
| - out <- outputStream(runConfig) |
91 |
| - _ <- processUntilStop( |
92 |
| - wantToClose, |
93 |
| - pageInstance, |
94 |
| - intf, |
95 |
| - sendQueue, |
96 |
| - out, |
97 |
| - receivedMessage, |
98 |
| - isComEnabled |
99 |
| - ) |
100 |
| - } yield () |
101 |
| - |
| 13 | + override val browserName: String, |
| 14 | + override val headless: Boolean, |
| 15 | + override val pwConfig: Config, |
| 16 | + override val runConfig: RunConfig, |
| 17 | + override val input: Seq[Input] |
| 18 | +) extends JSRun |
| 19 | + with Runner { |
| 20 | + scribe.debug(s"Creating CERun for $browserName") |
102 | 21 | lazy val future: Future[Unit] =
|
103 |
| - jsRunPrg(browserName, headless, enableCom, None) |
| 22 | + jsRunPrg(browserName, headless, isComEnabled = false, None) |
104 | 23 | .use(_ => IO.unit)
|
105 | 24 | .unsafeToFuture()
|
106 | 25 |
|
107 |
| - /** Stops the run and releases all the resources. |
108 |
| - * |
109 |
| - * This <strong>must</strong> be called to ensure the run's resources are |
110 |
| - * released. |
111 |
| - * |
112 |
| - * Whether or not this makes the run fail or not is up to the implementation. |
113 |
| - * However, in the following cases, calling [[close]] may not fail the run: |
114 |
| - * <ul> <li>[[future]] is already completed when [[close]] is called. |
115 |
| - * <li>This is a [[CERun]] and the event loop inside the VM is empty. |
116 |
| - * </ul> |
117 |
| - * |
118 |
| - * Idempotent, async, nothrow. |
119 |
| - */ |
120 |
| - |
121 |
| - override def close(): Unit = { |
122 |
| - wantToClose.set(true) |
123 |
| - scribe.info(s"StopSignal is ${wantToClose.get()}") |
124 |
| - } |
125 |
| - |
| 26 | + override protected def receivedMessage(msg: String): Unit = () |
126 | 27 | }
|
127 |
| -// browserName, headless, pwConfig, runConfig, input, onMessage |
128 |
| -class CEComRun( |
129 |
| - browserName: String, |
130 |
| - headless: Boolean, |
131 |
| - pwConfig: Config, |
132 |
| - runConfig: RunConfig, |
133 |
| - input: Seq[Input], |
134 |
| - onMessage: String => Unit |
135 |
| -) extends CERun( |
136 |
| - browserName, |
137 |
| - headless, |
138 |
| - pwConfig, |
139 |
| - runConfig, |
140 |
| - input |
141 |
| - ) |
142 |
| - with JSComRun { |
143 |
| - // enableCom is false for CERun and true for CEComRun |
144 |
| - override protected val enableCom = true |
145 |
| - // send is called only from JSComRun |
146 |
| - override def send(msg: String): Unit = sendQueue.offer(msg) |
147 |
| - // receivedMessage is called only from JSComRun. Hence its implementation is empty in CERun |
148 |
| - override protected def receivedMessage(msg: String): Unit = onMessage(msg) |
149 |
| -} |
150 |
| - |
151 |
| -private class WindowOnErrorException(errs: List[String]) |
152 |
| - extends Exception(s"JS error: $errs") |
0 commit comments