<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: nagaya-shion</title>
    <description>The latest articles on DEV Community by nagaya-shion (@nagayashion).</description>
    <link>https://dev.to/nagayashion</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4189707%2F0fafe822-9ec4-4e2b-8966-727b8d488f33.jpg</url>
      <title>DEV Community: nagaya-shion</title>
      <link>https://dev.to/nagayashion</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nagayashion"/>
    <language>en</language>
    <item>
      <title>The Bug Report Your Developers Will Actually Thank You For</title>
      <dc:creator>nagaya-shion</dc:creator>
      <pubDate>Sat, 17 Oct 2026 02:06:46 +0000</pubDate>
      <link>https://dev.to/nagayashion/the-bug-report-your-developers-will-actually-thank-you-for-4kcp</link>
      <guid>https://dev.to/nagayashion/the-bug-report-your-developers-will-actually-thank-you-for-4kcp</guid>
      <description>&lt;p&gt;I've spent 5 years in QA — 3 of them at Japan's largest software testing firm, managing test teams for major game publishers, and now as a QA director. In that time I've read thousands of bug reports.&lt;/p&gt;

&lt;p&gt;Maybe 10% of them were actually useful on first read.&lt;/p&gt;

&lt;p&gt;The other 90% triggered the same ritual: a developer reads the report, can't reproduce it, writes "works on my machine", and the bug ping-pongs between QA and dev for three days. The bug didn't cost three days. &lt;strong&gt;The report did.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's the template I enforce on every team I run, and the reasoning behind each field.&lt;/p&gt;

&lt;h2&gt;
  
  
  The template
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Title&lt;/span&gt;
[Area] One-line summary: what breaks, under which condition

&lt;span class="gu"&gt;## Environment&lt;/span&gt;
Device / OS / Browser + version / App build or commit
Account type used (if relevant)

&lt;span class="gu"&gt;## Steps to Reproduce&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt; Numbered.
&lt;span class="p"&gt;2.&lt;/span&gt; Exact.
&lt;span class="p"&gt;3.&lt;/span&gt; From a clean state.

&lt;span class="gu"&gt;## Expected&lt;/span&gt;
What should happen (and WHY you believe that — spec link, design, or convention)

&lt;span class="gu"&gt;## Actual&lt;/span&gt;
What happens instead. Paste exact error text, never paraphrase it.

&lt;span class="gu"&gt;## Reproduction rate&lt;/span&gt;
n / m attempts (e.g. 4/5). "Sometimes" is not a number.

&lt;span class="gu"&gt;## Severity + why&lt;/span&gt;
High / Medium / Low — with one sentence of business impact.

&lt;span class="gu"&gt;## Evidence&lt;/span&gt;
Screenshot (annotated), screen recording, console/network log.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing exotic. The value is in the details most reports skip.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three fields everyone gets wrong
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Reproduction rate: "sometimes" is not a number
&lt;/h3&gt;

&lt;p&gt;"It sometimes fails" tells a developer nothing. "4/5 attempts with network throttled to Slow 3G, 2/5 on fast connection" tells them it's a race condition — before they've opened the code.&lt;/p&gt;

&lt;p&gt;When I find a flaky-looking bug, I run it five more times and &lt;em&gt;count&lt;/em&gt;. Those 10 minutes routinely save the developer half a day of guessing. The repro-rate line is the single highest-ROI sentence in the entire report.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Expected behavior needs a "because"
&lt;/h3&gt;

&lt;p&gt;Weak: &lt;em&gt;"Expected: works correctly."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Strong: &lt;em&gt;"Expected: the second click is ignored, because the button should disable on first submission (and a double POST here means a double charge on checkout)."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The "because" does two jobs: it tells the developer where the bar is, and it tells the triage meeting why the bug matters. Severity debates usually die the moment the expected behavior has a reason attached.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Severity is a business statement, not a feeling
&lt;/h3&gt;

&lt;p&gt;My rule of thumb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High&lt;/strong&gt;: blocks a core flow, loses data, or costs money (double charges, lost form submissions, broken checkout)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medium&lt;/strong&gt;: core flow survives, but a real user segment is hurt (an error message screen readers never announce, a layout broken on one device class)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low&lt;/strong&gt;: cosmetic, or an edge case with an easy workaround&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that &lt;em&gt;who is affected&lt;/em&gt; changes severity. A broken layout at 717px sounds Low — until you know 717px is exactly the half-open posture of foldable phones, a growing share of premium Android devices. (I test on a Motorola Razr for precisely this reason. The number of bugs living between Tailwind's &lt;code&gt;sm&lt;/code&gt; and &lt;code&gt;md&lt;/code&gt; breakpoints is remarkable.)&lt;/p&gt;

&lt;h2&gt;
  
  
  What "no bugs found" should look like
&lt;/h2&gt;

&lt;p&gt;The most undervalued deliverable in QA: the honest empty report.&lt;/p&gt;

&lt;p&gt;If I test a flow and find nothing critical, the client still gets a list of &lt;strong&gt;what was tested, how, on which devices, and what looks solid&lt;/strong&gt; — plus any usability observations that aren't bugs. "We checked and it's fine" is informational. "We checked X, Y, Z in these 4 environments and found nothing" is evidence.&lt;/p&gt;

&lt;p&gt;Teams that only reward found-bug counts end up with inflated Low-severity noise and no idea what's actually been covered. Coverage transparency beats bug-count theater.&lt;/p&gt;

&lt;h2&gt;
  
  
  A 30-second checklist before you hit send
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Could a developer reproduce this &lt;strong&gt;without asking me anything?&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Is the repro rate a number?&lt;/li&gt;
&lt;li&gt;[ ] Does "Expected" contain a &lt;em&gt;because&lt;/em&gt;?&lt;/li&gt;
&lt;li&gt;[ ] Does severity state the business impact?&lt;/li&gt;
&lt;li&gt;[ ] Is there at least one piece of visual evidence?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If all five are checked, your bug report is already in the top 10%.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm a QA director in Japan (ex-SHIFT, Japan's largest QA firm) and I offer manual QA &amp;amp; bug hunting as a freelance service — exploratory testing on real devices (Windows 11 / iPhone / foldable Android) with reports exactly like the template above. You can find me on &lt;a href="https://www.fiverr.com/shion_nagaya/manually-test-your-website-or-app-and-report-every-bug" rel="noopener noreferrer"&gt;Fiverr&lt;/a&gt; or at &lt;a href="https://s-nagaya.vercel.app" rel="noopener noreferrer"&gt;s-nagaya.vercel.app&lt;/a&gt;. My E2E automation work is over here: &lt;a href="https://www.fiverr.com/shion_nagaya/build-playwright-test-automation-with-claude-code-ai" rel="noopener noreferrer"&gt;AI-driven test automation with Claude Code + Playwright&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>qa</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Let Claude Code Write My Playwright Tests for a Month. Here's What Actually Worked</title>
      <dc:creator>nagaya-shion</dc:creator>
      <pubDate>Sat, 17 Oct 2026 02:03:33 +0000</pubDate>
      <link>https://dev.to/nagayashion/i-let-claude-code-write-my-playwright-tests-for-a-month-heres-what-actually-worked-15e3</link>
      <guid>https://dev.to/nagayashion/i-let-claude-code-write-my-playwright-tests-for-a-month-heres-what-actually-worked-15e3</guid>
      <description>&lt;p&gt;As a QA director at a Japanese IT company, I spent the last months building E2E test suites with an unusual pair programmer: Claude Code, Anthropic's AI coding agent. Not for a toy project — for production QA pipelines.&lt;/p&gt;

&lt;p&gt;Here's an honest breakdown of what AI is genuinely good at in test automation, where it fails, and the workflow that ended up sticking.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code is &lt;strong&gt;excellent&lt;/strong&gt; at generating Playwright test skeletons from plain-language flow descriptions — roughly 70% of the boilerplate work disappears.&lt;/li&gt;
&lt;li&gt;It is &lt;strong&gt;terrible&lt;/strong&gt; (without guardrails) at selector strategy and flaky-wait hygiene. You need conventions it must follow.&lt;/li&gt;
&lt;li&gt;The sweet spot: &lt;strong&gt;AI writes, human stabilizes.&lt;/strong&gt; My rule: every AI-generated test gets run 5× locally and once in CI before it counts as "done".&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Nothing exotic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your-app-e2e/
├── playwright.config.ts   # 3 projects: desktop / mobile / foldable
├── tests/
│   ├── pages/             # Page Object Model
│   │   ├── ContactPage.ts
│   │   └── DashboardPage.ts
│   └── e2e/
│       ├── contact-form.spec.ts
│       └── dashboard.spec.ts
└── ci/github-actions-e2e.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trick is in &lt;strong&gt;what you tell Claude Code before asking for tests&lt;/strong&gt;. I keep a &lt;code&gt;CLAUDE.md&lt;/code&gt; in the repo with three hard rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Test conventions (non-negotiable)&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt; Selectors: getByRole / getByLabel / [name=] attributes only.
   NEVER CSS class chains.
&lt;span class="p"&gt;2.&lt;/span&gt; No waitForTimeout. Playwright auto-waiting + expect() polling only.
&lt;span class="p"&gt;3.&lt;/span&gt; Every test must pass in isolation AND in parallel (no shared state).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these three lines, the quality of generated tests jumps dramatically. Without them, you get &lt;code&gt;page.locator('.css-1kxonj9 &amp;gt; div:nth-child(3)')&lt;/code&gt; and &lt;code&gt;waitForTimeout(3000)&lt;/code&gt; — the stuff flaky suites are made of.&lt;/p&gt;

&lt;h2&gt;
  
  
  What AI-generated tests look like (real example)
&lt;/h2&gt;

&lt;p&gt;I asked Claude Code: &lt;em&gt;"Write tests for the contact form: success, server error, pending state. Never hit the real API."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It produced a Page Object with network stubbing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** Stub the contact API so tests never send real notifications. */&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;mockContactApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delayMs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;**/api/contact&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;delayMs&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delayMs&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fulfill&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
          &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Submission failed.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And a pending-state test I honestly wouldn't have bothered writing by hand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;disables the submit button while the request is in flight&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1.5s of artificial latency makes the pending state observable.&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockContactApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillValidForm&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;submitButton&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeDisabled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;successHeading&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last test caught a real bug class I see constantly in manual QA: &lt;strong&gt;double submission&lt;/strong&gt;. The button only disabled after a React re-render — two fast clicks under slow network = two POST requests. On a contact form that's an annoyance; on a checkout it's a double charge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the AI fails (and how I patched it)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. It trusts the DOM too much.&lt;/strong&gt; Generated selectors matched what exists today, including auto-generated class names. Fix: the conventions file above, plus review of every selector during stabilization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. It doesn't know what's worth testing.&lt;/strong&gt; Ask for "tests for the dashboard" and you get 15 shallow assertions about text being visible. The test &lt;em&gt;plan&lt;/em&gt; still has to come from a human who understands risk: payment flows, auth edge cases, state transitions. I write the plan; AI writes the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. It can't feel flakiness.&lt;/strong&gt; An AI-generated test that passes once isn't done. My stabilization loop: run 5× locally (&lt;code&gt;--repeat-each=5&lt;/code&gt;), once in CI, review traces for silent retries. About 1 in 10 generated tests needs a rework at this stage.&lt;/p&gt;

&lt;h2&gt;
  
  
  An underrated trick: test the viewports nobody tests
&lt;/h2&gt;

&lt;p&gt;My config includes a project most suites never have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Foldable half-open posture — where responsive bugs hide.&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foldable-half-open&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;viewport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;717&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1172&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;isMobile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hasTouch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;717px sits between Tailwind's &lt;code&gt;sm&lt;/code&gt; and &lt;code&gt;md&lt;/code&gt; breakpoints. I own a foldable (Motorola Razr), and the number of layout bugs living exactly in that gap is remarkable. Costs one config block, catches a bug class your users on premium Android devices hit daily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results after a month
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Test authoring time: roughly −60%.&lt;/strong&gt; The plan takes as long as before; the code doesn't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coverage went up&lt;/strong&gt;, because tedious-to-write tests (pending states, error paths, viewport edge cases) stopped being skipped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance stayed manageable&lt;/strong&gt; — but only because of the selector conventions. I've seen AI-generated suites without conventions, and they rot in weeks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The honest summary: Claude Code didn't replace QA judgment. It replaced QA typing.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm a QA director in Japan (ex-SHIFT, Japan's largest QA firm) and I build Playwright + Claude Code test suites as a freelance service — async, text-first, from JST. If your team wants a suite like this, you can find me on &lt;a href="https://www.fiverr.com/shion_nagaya/build-playwright-test-automation-with-claude-code-ai" rel="noopener noreferrer"&gt;Fiverr&lt;/a&gt; or see more at &lt;a href="https://s-nagaya.vercel.app" rel="noopener noreferrer"&gt;s-nagaya.vercel.app&lt;/a&gt;. Questions about the workflow are welcome in the comments — happy to share the conventions file.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>playwright</category>
      <category>testing</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
