<h3 dir="auto">Feature request</h3>
<p dir="auto">Given playwright has its own test runner, I was expecting to be able to drop the use of jest for simple unit testing in favour of <code class="notranslate">@playwright/test</code> which would simplify a lot of things..</p>
<ul dir="auto">
<li>No need to install, configure jest</li>
<li>All tests could be invoked with a simple glob, rather than having to partition my test scripts into jest vs. playwright tests</li>
</ul>
<p dir="auto">Unfortunately, because some of the elements I'm unit testing live alongside React components, they are in .tsx files, such as this simple counter example, meaning I can't import the business logic elements without having .tsx support in playwright...</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import React from &quot;react&quot;;
import { Immutable, Store } from &quot;@lauf/store&quot;;
import { useSelected, useStore } from &quot;@lauf/store-react&quot;;

/** BUSINESS LOGIC */

export interface AppState {
  counter: number;
}

export const INITIAL_STATE: Immutable&lt;AppState&gt; = {
  counter: 0
} as const;

export const increment = (store: Store&lt;AppState&gt;) =&gt;
  store.edit((draft) =&gt; (draft.counter += 1));

export const decrement = (store: Store&lt;AppState&gt;) =&gt;
  store.edit((draft) =&gt; (draft.counter -= 1));

/** UI BINDINGS */

interface StoreProps {
  store: Store&lt;AppState&gt;;
}

const Display = ({ store }: StoreProps) =&gt; {
  const counter = useSelected(store, (state) =&gt; state.counter);
  return &lt;h1&gt;{counter}&lt;/h1&gt;;
};

const IncreaseButton = ({ store }: StoreProps) =&gt; (
  &lt;button onClick={() =&gt; increment(store)}&gt;Increase&lt;/button&gt;
);

const DecreaseButton = ({ store }: StoreProps) =&gt; (
  &lt;button onClick={() =&gt; decrement(store)}&gt;Decrease&lt;/button&gt;
);

export const App = () =&gt; {
  const store = useStore(INITIAL_STATE);
  return (
    &lt;&gt;
      &lt;Display store={store} /&gt;
      &lt;IncreaseButton store={store} /&gt;
      &lt;DecreaseButton store={store} /&gt;
    &lt;/&gt;
  );
};
"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-smi">React</span> <span class="pl-k">from</span> <span class="pl-s">"react"</span><span class="pl-kos">;</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-smi">Immutable</span><span class="pl-kos">,</span> <span class="pl-smi">Store</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"@lauf/store"</span><span class="pl-kos">;</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span> <span class="pl-s1">useSelected</span><span class="pl-kos">,</span> <span class="pl-s1">useStore</span> <span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">"@lauf/store-react"</span><span class="pl-kos">;</span>

<span class="pl-c">/** BUSINESS LOGIC */</span>

<span class="pl-k">export</span> <span class="pl-k">interface</span> <span class="pl-smi">AppState</span> <span class="pl-kos">{</span>
  <span class="pl-c1">counter</span>: <span class="pl-smi">number</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">export</span> <span class="pl-k">const</span> <span class="pl-smi">INITIAL_STATE</span>: <span class="pl-smi">Immutable</span><span class="pl-kos">&lt;</span><span class="pl-smi">AppState</span><span class="pl-kos">&gt;</span> <span class="pl-c1">=</span> <span class="pl-kos">{</span>
  <span class="pl-c1">counter</span>: <span class="pl-c1">0</span>
<span class="pl-kos">}</span> <span class="pl-k">as</span> <span class="pl-smi">const</span><span class="pl-kos">;</span>

<span class="pl-k">export</span> <span class="pl-k">const</span> <span class="pl-en">increment</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s1">store</span>: <span class="pl-smi">Store</span><span class="pl-kos">&lt;</span><span class="pl-smi">AppState</span><span class="pl-kos">&gt;</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span>
  <span class="pl-s1">store</span><span class="pl-kos">.</span><span class="pl-en">edit</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">draft</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span><span class="pl-s1">draft</span><span class="pl-kos">.</span><span class="pl-c1">counter</span> <span class="pl-c1">+=</span> <span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">export</span> <span class="pl-k">const</span> <span class="pl-en">decrement</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s1">store</span>: <span class="pl-smi">Store</span><span class="pl-kos">&lt;</span><span class="pl-smi">AppState</span><span class="pl-kos">&gt;</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span>
  <span class="pl-s1">store</span><span class="pl-kos">.</span><span class="pl-en">edit</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">draft</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span><span class="pl-s1">draft</span><span class="pl-kos">.</span><span class="pl-c1">counter</span> <span class="pl-c1">-=</span> <span class="pl-c1">1</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-c">/** UI BINDINGS */</span>

<span class="pl-k">interface</span> <span class="pl-smi">StoreProps</span> <span class="pl-kos">{</span>
  <span class="pl-c1">store</span>: <span class="pl-smi">Store</span><span class="pl-kos">&lt;</span><span class="pl-smi">AppState</span><span class="pl-kos">&gt;</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span>

<span class="pl-k">const</span> <span class="pl-smi">Display</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-kos">{</span> store <span class="pl-kos">}</span>: <span class="pl-smi">StoreProps</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-k">const</span> <span class="pl-s1">counter</span> <span class="pl-c1">=</span> <span class="pl-en">useSelected</span><span class="pl-kos">(</span><span class="pl-s1">store</span><span class="pl-kos">,</span> <span class="pl-kos">(</span><span class="pl-s1">state</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">state</span><span class="pl-kos">.</span><span class="pl-c1">counter</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-k">return</span> <span class="pl-kos">&lt;</span><span class="pl-smi">h1</span><span class="pl-kos">&gt;</span><span class="pl-kos">{</span>counter<span class="pl-kos">}</span><span class="pl-c1">&lt;</span><span class="pl-pds"><span class="pl-c1">/</span>h1&gt;;</span><span class="pl-c1"></span>
<span class="pl-kos">}</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-smi">IncreaseButton</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-kos">{</span> store <span class="pl-kos">}</span>: <span class="pl-smi">StoreProps</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span>
  <span class="pl-c1">&lt;</span><span class="pl-s1">button</span> <span class="pl-smi">onClick</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-c1">increment</span><span class="pl-kos">(</span><span class="pl-s1">store</span><span class="pl-kos">)</span><span class="pl-kos">}</span><span class="pl-c1">&gt;</span><span class="pl-smi">Increase</span><span class="pl-c1">&lt;</span><span class="pl-pds"><span class="pl-c1">/</span>button&gt;</span><span class="pl-c1"></span>
<span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">const</span> <span class="pl-smi">DecreaseButton</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-kos">{</span> store <span class="pl-kos">}</span>: <span class="pl-smi">StoreProps</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span>
  <span class="pl-c1">&lt;</span><span class="pl-s1">button</span> <span class="pl-smi">onClick</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-c1">decrement</span><span class="pl-kos">(</span><span class="pl-s1">store</span><span class="pl-kos">)</span><span class="pl-kos">}</span><span class="pl-c1">&gt;</span><span class="pl-smi">Decrease</span><span class="pl-c1">&lt;</span><span class="pl-pds"><span class="pl-c1">/</span>button&gt;</span><span class="pl-c1"></span>
<span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">export</span> <span class="pl-k">const</span> <span class="pl-smi">App</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
  <span class="pl-k">const</span> <span class="pl-s1">store</span> <span class="pl-c1">=</span> <span class="pl-en">useStore</span><span class="pl-kos">(</span><span class="pl-smi">INITIAL_STATE</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-k">return</span> <span class="pl-kos">(</span>
    <span class="pl-c1">&lt;</span><span class="pl-c1">&gt;</span>
      <span class="pl-c1">&lt;</span><span class="pl-smi">Display</span> <span class="pl-s1">store</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-c1">store</span><span class="pl-kos">}</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
      <span class="pl-c1">&lt;</span><span class="pl-smi">IncreaseButton</span> <span class="pl-s1">store</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-c1">store</span><span class="pl-kos">}</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
      <span class="pl-c1">&lt;</span><span class="pl-smi">DecreaseButton</span> <span class="pl-s1">store</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-c1">store</span><span class="pl-kos">}</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
    <span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
  <span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-kos">}</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">For now I'll have to go back to jest for half my tests, but not because any functionality is missing in playwright as far as I can see, it's just about transpilation support from the .tsx targets.</p>
<h3 dir="auto">System info</h3>
<ul dir="auto">
<li>Playwright Version: <code class="notranslate">v1.34.1, v1.33.0</code></li>
<li>Operating System: <code class="notranslate">Ubuntu Jammy</code></li>
<li>Browser: <code class="notranslate">All</code></li>
<li>Other info: This is a bug that affects the Docker image <code class="notranslate">mcr.microsoft.com/playwright:v1.33.0</code></li>
</ul>
<h3 dir="auto">Source code</h3>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I provided exact source code that allows reproducing the issue locally.</li>
</ul>




<p dir="auto"><strong>Steps</strong></p>
<ul dir="auto">
<li>
<p dir="auto">Run this to download the image and get a shell</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="docker run -it --rm --ipc=host mcr.microsoft.com/playwright:v1.33.0 /bin/bash"><pre class="notranslate"><code class="notranslate">docker run -it --rm --ipc=host mcr.microsoft.com/playwright:v1.33.0 /bin/bash
</code></pre></div>
</li>
<li>
<p dir="auto">Try a simple playwright command inside the docker container</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="npx playwright --version"><pre class="notranslate"><code class="notranslate">npx playwright --version
</code></pre></div>
</li>
</ul>
<p dir="auto"><strong>Expected</strong></p>
<p dir="auto">It prints <code class="notranslate">Version 1.33.0</code> to stdout</p>
<p dir="auto">i.e. do what the <code class="notranslate">mcr.microsoft.com/playwright:v1.34.0</code> container does</p>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://user-images.githubusercontent.com/24650490/240334900-bc1c3723-5799-4e15-83a7-d25b032704d7.png"><img src="https://user-images.githubusercontent.com/24650490/240334900-bc1c3723-5799-4e15-83a7-d25b032704d7.png" alt="image" style="max-width: 100%;"></a></p>
<p dir="auto"><strong>Actual</strong></p>
<p dir="auto">It asks to install playwright@1.34.1</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Need to install the following packages:
  playwright@1.34.1
Ok to proceed? (y)"><pre class="notranslate"><code class="notranslate">Need to install the following packages:
  playwright@1.34.1
Ok to proceed? (y)
</code></pre></div>
<p dir="auto"><a target="_blank" rel="noopener noreferrer" href="https://user-images.githubusercontent.com/24650490/240334551-6548fc11-3cd9-4772-8d3f-58d67dcc57ff.png"><img src="https://user-images.githubusercontent.com/24650490/240334551-6548fc11-3cd9-4772-8d3f-58d67dcc57ff.png" alt="image" style="max-width: 100%;"></a></p>