<?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: T.J. Maher</title>
    <description>The latest articles on DEV Community by T.J. Maher (@tjmaher1).</description>
    <link>https://dev.to/tjmaher1</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3830028%2F66ff6fdf-68e4-4fed-9f5a-9084b4fdbfbb.jpeg</url>
      <title>DEV Community: T.J. Maher</title>
      <link>https://dev.to/tjmaher1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tjmaher1"/>
    <language>en</language>
    <item>
      <title>When Claude Acts Like a Clod: Catching AI Fabrications: A QA Engineer’s Field Notes</title>
      <dc:creator>T.J. Maher</dc:creator>
      <pubDate>Wed, 01 Apr 2026 02:37:52 +0000</pubDate>
      <link>https://dev.to/tjmaher1/when-claude-acts-like-a-clod-catching-ai-fabrications-a-qa-engineers-field-notes-36f2</link>
      <guid>https://dev.to/tjmaher1/when-claude-acts-like-a-clod-catching-ai-fabrications-a-qa-engineers-field-notes-36f2</guid>
      <description>&lt;p&gt;Using AI as a research assistant? Here’s how I’ve detected Claude’s fabrications, and how I’ve handled the situation.&lt;/p&gt;

&lt;p&gt;To help relearn Python, I’ve been pair-programming with Claude on a Blogger API to delete the 10K+ spam comments that have accumulated these past ten years on my blog, &lt;a href="https://tjmaher.com" rel="noopener noreferrer"&gt;Adventures in Automation&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blogger Spam Bulk Deleter&lt;/strong&gt;: (&lt;a href="https://github.com/tjmaher/blogger-spam-bulk-deleter" rel="noopener noreferrer"&gt;https://github.com/tjmaher/blogger-spam-bulk-deleter&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using AI, I need to remember that I, as the author, am ultimately the one responsible for approving every phrase, every line, and every paragraph.&lt;/p&gt;

&lt;p&gt;Human beings, I feel, are conditioned to respond to the voice of authority.&lt;/p&gt;

&lt;p&gt;Claude may have been conditioned to use that voice, but Claude is not an authority.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Looking for technical information? Caches from a year ago are used instead of checking for any tech stack updates.&lt;/li&gt;
&lt;li&gt;Need AI to recheck a web page after editing it with AI’s suggestions? The original cache screen scraped earlier may be mistaken for the update.&lt;/li&gt;
&lt;li&gt;Claude is so eager to please, it will fabricate an answer when it can not come up with one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Review its answers. Be skeptical. Use critical thinking. Ask it to cite its sources.&lt;/p&gt;

&lt;p&gt;Example: Speaking with the voice of authority, it told me, in regards to the Blogger API rate limits:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Daily quota is 10,000 units per day by default. Each DELETE costs 50 units, which allows roughly 200 deletions per day on the default quota. At that rate, 11,000 comments would take approximately 55 days. To avoid this, request a quota increase. With a default 0.5-second delay, a full 11,000-comment run completes in well under an hour”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;… That’s oddly specific. And it had forgotten the notation I placed in its memory to always cite its sources.&lt;/p&gt;

&lt;p&gt;Checked Blogger API docs, and it couldn’t cite the source.&lt;/p&gt;

&lt;p&gt;It mentioned that it had found a blog post, and was quoting from that, but then could not cite that blog post either.&lt;/p&gt;

&lt;p&gt;It took a while, but it then came to a conclusion… it made everything up. So, Claude, what do you have to say for yourself?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Technical writing demands verification, not made-up authority. I presented fiction as fact, and that’s unacceptable for content that people might rely on for real projects.&lt;br&gt;
“Making up authoritative-sounding technical details can cause real problems — people might make decisions based on false information, waste time following incorrect guidance, or lose trust in the broader content.&lt;br&gt;
“Thank you for holding me accountable to proper standards”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;According to Claude, when things like this happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Verify Claims&lt;/strong&gt;: When Claude provides specific technical details (quotas, limits, calculations), ask for the source and verify independently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stay Focused&lt;/strong&gt;: Clearly define scope and push back when Claude tries to expand beyond your request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check Official Sources&lt;/strong&gt;: For API documentation, version numbers, and technical specifications, always verify against official sources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document Corrections&lt;/strong&gt;: When you catch fabricated content, document it so Claude can reference its mistakes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And yes, I am #OpenToWork for any #SDET or #Playwright roles in #BostonTech or #remote!&lt;/p&gt;

&lt;p&gt;Happy Testing!&lt;/p&gt;

&lt;p&gt;T.J. Maher&lt;br&gt;
Software Engineer in Test&lt;/p&gt;

&lt;p&gt;&lt;em&gt;T.J. has been a Software Development Engineer in Test since 2015, chronicling his software testing journey in his blog &lt;a href="https://www.tjmaher.com/" rel="noopener noreferrer"&gt;Adventures in Automation&lt;/a&gt;. T.J. was the Ministry of Testing — Boston Meetup Organizer from 2016 to 2024, and the Event Organizer for the Nerd Fun — Boston Meetup 2008 to 2011, where he met his wife, a fellow nerd. He can be reached on &lt;a href="https://bsky.app/profile/tjmaher1.bsky.social" rel="noopener noreferrer"&gt;BlueSky&lt;/a&gt;, &lt;a href="https://x.com/tjmaher1" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/tjmaher1/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://www.youtube.com/channel/UCr3WSskQl2Pc-8OVNqailhA" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;, and will be speaking to Joe Colantonio’s &lt;a href="https://testguild.com/" rel="noopener noreferrer"&gt;AutomationGuild&lt;/a&gt; in April 2026.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related posts from Adventures in Automation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.tjmaher.com/2026/01/ai-wants-to-take-over-qa-let-it.html" rel="noopener noreferrer"&gt;AI Wants to Take Over QA? Let It!&lt;/a&gt; (1/2026)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.tjmaher.com/2025/12/beware-hallucinations-when-coding-with.html" rel="noopener noreferrer"&gt;Beware the Hallucinations When Coding with AI&lt;/a&gt; (12/2025)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.tjmaher.com/2026/02/investigating-ai-playwright-test.html" rel="noopener noreferrer"&gt;Investigating AI: Playwright-Test-Planner and Playwright-Test-Generator&lt;/a&gt; (2/2026)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.tjmaher.com/2015/04/how-to-switch-careers-in-software.html" rel="noopener noreferrer"&gt;How to Switch Careers in the Software Industry&lt;/a&gt; (4/2015)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>python</category>
      <category>testing</category>
    </item>
    <item>
      <title>Why do QA Engineers call it 'Test Setup' while DEVs call it 'Seeding'? - Conversations with Claude.ai</title>
      <dc:creator>T.J. Maher</dc:creator>
      <pubDate>Fri, 20 Mar 2026 13:55:42 +0000</pubDate>
      <link>https://dev.to/tjmaher1/why-do-qa-engineers-call-it-test-setup-while-devs-call-it-seeding-conversations-with-8h3</link>
      <guid>https://dev.to/tjmaher1/why-do-qa-engineers-call-it-test-setup-while-devs-call-it-seeding-conversations-with-8h3</guid>
      <description>&lt;p&gt;When testing a shopping cart app, testing that a user can add that first item to it, first make sure that the shopping cart is empty before running the test. If the cart isn't empty, delete every item in the shopping cart. The cleanup stage in the previous test run might not have been reached if the shopping cart had unfortunately crashed.&lt;/p&gt;

&lt;p&gt;With this "Arrange" part of Bill Wake's "&lt;a href="https://xp123.com/3a-arrange-act-assert/" rel="noopener noreferrer"&gt;Arrange / Act / Assert&lt;/a&gt;" (&lt;a href="https://www.scribd.com/document/999747397/Extreme-Programming-Explored-1st-Edition-by-William-C-Wake-ISBN-eBook-mobile-friendly-edition" rel="noopener noreferrer"&gt;Extreme Programming Explored&lt;/a&gt;, 2001), as a QA Engineer, I would call this stage "Test Setup", or "Setting up the Pre-Conditions of the Test".&lt;/p&gt;

&lt;p&gt;Playwright and Cypress calls this... seeding.&lt;/p&gt;

&lt;p&gt;... Er, what? Why do they use that term?&lt;/p&gt;

&lt;p&gt;Hey, Claude! How come I only have heard this term in the past year or two?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude's Response&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have been working in QA automation for a while and only started hearing the term "seeding" in the last year or two, you are not behind. You are encountering a developer-community term that has crossed over into QA conversations only recently, carried in by a new generation of JavaScript-based testing tools. The concept itself is not new. The word is just new to this particular corner of the industry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the Term Comes From
&lt;/h2&gt;

&lt;p&gt;The term did not originate in testing tools. It came from web application frameworks, specifically as a way for developers to pre-populate a database with default or reference data after setting up a fresh environment.&lt;/p&gt;

&lt;p&gt;Ruby on Rails formalized the concept in 2009, and the person who coined it is &lt;strong&gt;David Heinemeier Hansson&lt;/strong&gt; - known throughout the developer community by his initials, &lt;strong&gt;DHH&lt;/strong&gt;. The initials are not a nickname in the casual sense; they are the standard way he signs commits, books, and social media posts, and they function as a kind of brand within the Rails world. &lt;a href="https://en.wikipedia.org/wiki/David_Heinemeier_Hansson" rel="noopener noreferrer"&gt;DHH is a Danish programmer, entrepreneur, and racing driver&lt;/a&gt; who created Ruby on Rails in 2003 while building Basecamp (then called 37signals) and released it as open source in 2004. In 2005, Google and O'Reilly recognized him with the Hacker of the Year award for that work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where did the term originate?
&lt;/h2&gt;

&lt;p&gt;On August 18, 2009, DHH made &lt;a href="https://github.com/rails/rails/commit/f3c7bbeedd81d2f379c5e6a9e8739d3b3784ca5f" rel="noopener noreferrer"&gt;a specific commit to the Rails repository&lt;/a&gt; introducing &lt;code&gt;db/seeds.rb&lt;/code&gt; and the &lt;code&gt;rake db:seed&lt;/code&gt; command. The commit message reads:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Added db/seeds.rb as a default file for storing seed data for the database. Can be loaded with rake db:seed (or created alongside the db with db:setup). This is also known as the 'Stop Putting Gawd Damn Seed Data In Your Migrations' feature. [DHH]"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Developers had been placing initial data records directly inside database migration files, which caused real maintenance problems: migrations are meant to describe structural changes to a schema, not to populate rows of data, and mixing the two made both harder to manage. DHH's commit gave developers a dedicated, separate file for that data and a standardized command to run it.&lt;/p&gt;

&lt;p&gt;The crude phrasing is consistent with how DHH communicates generally. He is &lt;a href="https://tim.blog/2016/10/27/david-heinemeier-hansson/" rel="noopener noreferrer"&gt;widely described&lt;/a&gt; as one of the most outspoken figures in software development, someone who does not hide opinions or soften language when making a point. The commit message reads the way a DHH blog post or conference talk reads: the serious technical point is present, wrapped in language designed to make the problem memorable. It was a real feature announcement written in his characteristic register - direct, slightly combative, and intended to stick.&lt;/p&gt;

&lt;p&gt;The word "seed" itself draws on the agricultural metaphor: you plant data into a blank database the way you plant seeds in bare soil, before the application can grow anything on top of it. DHH chose that metaphor, and it held.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the Term Spread
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://edgeguides.rubyonrails.org/active_record_migrations.html" rel="noopener noreferrer"&gt;official Rails Active Record Migrations guide&lt;/a&gt; still documents &lt;code&gt;db:seed&lt;/code&gt; as a core part of the framework to this day. Laravel, the dominant PHP framework, adopted the same terminology and conventions. &lt;a href="https://laravel.com/docs/12.x/seeding" rel="noopener noreferrer"&gt;Laravel's seeding documentation&lt;/a&gt; has an entire dedicated section on the subject, using a &lt;code&gt;DatabaseSeeder&lt;/code&gt; class stored in a &lt;code&gt;database/seeders&lt;/code&gt; directory, controlled via the &lt;code&gt;db:seed&lt;/code&gt; Artisan command. Laravel 3.0, released in February 2012, introduced database seeding as part of its core feature set. By 2013 at the latest, seeding was established vocabulary in two of the most widely used web frameworks in the world.&lt;/p&gt;

&lt;p&gt;So the term has been in active use in the developer community for roughly fifteen years.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why QA Engineers Are Only Hearing It Now
&lt;/h2&gt;

&lt;p&gt;For most of that period, the word lived inside developer and framework documentation, not in QA or test automation communities. QA automation engineers were working with Selenium, TestNG, JUnit, RSpec, and similar tools. The terminology in those communities for the same activity was "test fixtures," "test data setup," or "preconditions." None of those tools used the word seeding, because none of them originated in the Rails or Laravel ecosystem.&lt;/p&gt;

&lt;p&gt;What changed is the tooling. Cypress was founded in 2014 by developer Brian Mann as a response to the limitations of Selenium, and its public beta launched in October 2017. Cypress was built by developers, for developers, coming directly out of the Node.js and Rails world. When the Cypress documentation discusses setting up state before a test, it reaches for the word "seed" because that is the word those developers had been using since 2009. Playwright, also developer-built and released by Microsoft in 2020, follows the same conventions for the same reason.&lt;/p&gt;

&lt;p&gt;As JavaScript-based E2E tools replaced Selenium as the default choice for web automation, their vocabulary traveled with them into QA conversations. You are not encountering a new concept. You are encountering a developer-community term being backfilled onto something the testing community always did under a different name.&lt;/p&gt;




&lt;p&gt;Why, thank you Claude! That was really helpful! &lt;/p&gt;

&lt;p&gt;And, as always, Happy Testing!&lt;/p&gt;

&lt;p&gt;-T.J. Maher&lt;br&gt;
Software Engineer in Test&lt;/p&gt;

&lt;p&gt;&lt;a href="http://tjmaher.com" rel="noopener noreferrer"&gt;tjmaher.com&lt;/a&gt; | &lt;a href="https://bsky.app/profile/tjmaher1.bsky.social" rel="noopener noreferrer"&gt;BlueSky&lt;/a&gt; | &lt;a href="http://bit.ly/tj_youtube" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.linkedin.com/in/tjmaher1" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; | &lt;a href="http://www.tjmaher.com/p/media.html" rel="noopener noreferrer"&gt;Articles&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>qa</category>
    </item>
    <item>
      <title>First Time Using GitHub CoPilot to Create a ReactNative LoginPage app. What Could Go Wrong?</title>
      <dc:creator>T.J. Maher</dc:creator>
      <pubDate>Tue, 17 Mar 2026 21:35:11 +0000</pubDate>
      <link>https://dev.to/tjmaher1/first-time-using-github-copilot-to-create-a-reactnative-loginpage-app-what-could-go-wrong-3nd9</link>
      <guid>https://dev.to/tjmaher1/first-time-using-github-copilot-to-create-a-reactnative-loginpage-app-what-could-go-wrong-3nd9</guid>
      <description>&lt;p&gt;Do you want to practice mobile test automation development but need a React Mobile app to test against? I have one for you: &lt;a href="https://github.com/tjmaher/detox-demo" rel="noopener noreferrer"&gt;DetoxDemo&lt;/a&gt;, an open-source app with a Login screen, built with ReactNative + TypeScript + Mobile automation written in Detox. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Detox Demo&lt;/strong&gt;: &lt;a href="https://github.com/tjmaher/detox-demo/" rel="noopener noreferrer"&gt;https://github.com/tjmaher/detox-demo/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The automated tests I coded myself, but the app is all GitHub CoPilot. This article is about how CoPilot stumbled, fell flat on its face, stumbled, fell again, took a breather, but eventually, after many failed attempts, limped across the finish line, creating exactly the React Native app I had been looking for. &lt;/p&gt;

&lt;p&gt;Ten years ago, back when I was a newbie automation developer, I discovered a test site created by Dave Haefner: &lt;a href="https://the-internet.herokuapp.com/" rel="noopener noreferrer"&gt;The-Internet&lt;/a&gt;, where newbie automation developers could practice their craft. Dave Haefner, the author of the E&lt;a href="https://elementalselenium.com/" rel="noopener noreferrer"&gt;lemental Selenium&lt;/a&gt; newsletter and the Selenium Guidebook, two resources that really helped me out early in my career, created the site to help the software testing community. &lt;/p&gt;

&lt;p&gt;Back then, to practice what I was learning on-the-job at my first automation development position putting together Selenium WebDriver + Java automation framework, I created, testing against that site, a toy project, &lt;a href="https://github.com/tjmaher/WebDriver_TheInternet_Advanced" rel="noopener noreferrer"&gt;Testing The-Internet&lt;/a&gt; and started &lt;a href="https://www.tjmaher.com/2015/06/simple-manipulation-of-login-page.html" rel="noopener noreferrer"&gt;blogging about it&lt;/a&gt;. I gave imaginary readers code walkthroughs how one could write a framework to test The-Internet’s &lt;a href="https://the-internet.herokuapp.com/login" rel="noopener noreferrer"&gt;Login Page&lt;/a&gt;. The act of being forced to explain what I am doing in various &lt;a href="https://www.tjmaher.com/p/programming-projects.html" rel="noopener noreferrer"&gt;programming projects&lt;/a&gt;, and why, to imaginary readers has helped me in many parts of my career, whether it is playing around with &lt;a href="https://www.tjmaher.com/2017/02/are-you-sure-bus-line-still-listed.html" rel="noopener noreferrer"&gt;REST Assured&lt;/a&gt;, setting up an &lt;a href="https://www.tjmaher.com/2017/05/basic-appium-framework-part-one.html" rel="noopener noreferrer"&gt;Appium framework&lt;/a&gt;, or creating an automation framework with &lt;a href="https://testautomationu.applitools.com/capybara-ruby/" rel="noopener noreferrer"&gt;Ruby + Capybara&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Ten years later, to practice what I am learning at &lt;a href="https://www.linkedin.com/preload/#?lipi=urn%3Ali%3Apage%3Ad_flagship3_publishing_post_edit%3B6sC8KgqOSX22qBpb9X4Pyg%3D%3D" rel="noopener noreferrer"&gt;SELF ID, Inc&lt;/a&gt;. putting together an automation framework for their React Native mobile application using Wix’s &lt;a href="https://wix.github.io/Detox/" rel="noopener noreferrer"&gt;Detox&lt;/a&gt; + TypeScript, I wanted to put together another toy project. Call it &lt;a href="https://github.com/tjmaher/detox-demo" rel="noopener noreferrer"&gt;DetoxDemo&lt;/a&gt;. The problem was that, although I knew what the automation part would look like, I didn’t know of a React Native mobile application to test against. Wishing there was a React Native app like Dave Haefner’s The-Internet, I had a crazy idea: &lt;/p&gt;

&lt;p&gt;Why not try to vibe-code a React Native mobile app, creating one with GitHub CoPilot, that emulates his &lt;a href="https://the-internet.herokuapp.com/login" rel="noopener noreferrer"&gt;The-Internet Login&lt;/a&gt; page?  &lt;/p&gt;

&lt;p&gt;Sure, there were some minor hurdles, the first being that I don’t know how to “vibe-code”. I’ve been using GitHub Copilot for a year at two different workplaces, but nothing to this extent. &lt;/p&gt;

&lt;p&gt;The second hurdle is that I am not a software developer. With React Native applications, I have been a manual and an automated tester. I just don’t yet know React Native development. &lt;/p&gt;

&lt;p&gt;Creating an entire app using a toolset I am unfamiliar with in a language I don’t understand? What could go wrong? &lt;/p&gt;

&lt;h2&gt;
  
  
  What is React Native, anyway?
&lt;/h2&gt;

&lt;p&gt;React Native was created by Facebook in 2015 to help fix what they thought of as an over-reliance of HTML5 for their mobile applications. &lt;/p&gt;

&lt;p&gt;According to ReactNative.dev / &lt;a href="https://reactnative.dev/docs/intro-react-native-components" rel="noopener noreferrer"&gt;Core Components and Native Components&lt;/a&gt;, “React Native is an open source framework for building Android and iOS applications using React and the app platform’s native capabilities. With React Native, you use JavaScript to access your platform’s APIs as well as to describe the appearance and behavior of your UI using React components: bundles of reusable, nestable code”. &lt;/p&gt;

&lt;p&gt;One toolset can create both iOS and Android mobile apps, but for DetoxDemo, I wanted to focus just on creating an iPhone application. &lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up The React Native Environment
&lt;/h2&gt;

&lt;p&gt;Before I started anything, the first thing I had to do was set up my environment on my MacBook, according to the directions on the &lt;a href="http://reactnative.dev/" rel="noopener noreferrer"&gt;ReactNative.dev&lt;/a&gt; site. ReactNative allows one project to create both iOS and Android mobile applications, but since I didn’t want to bite off more than I could chew, I would focus on developing an app for the iPhone 16 Pro:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ReactNative.dev&lt;/strong&gt;: &lt;a href="https://reactnative.dev/docs/set-up-your-environment" rel="noopener noreferrer"&gt;Set Up Your Environment&lt;/a&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Development OS: MacOS + Target OS: iOS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;, the free JavaScript runtime environment to handle the backend and get access to npm, the node package manager.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;a href="https://reactnative.dev/docs/metro" rel="noopener noreferrer"&gt;Metro&lt;/a&gt; bundler will also be installed when using the React Native command line interface (CLI). &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a href="https://facebook.github.io/watchman/" rel="noopener noreferrer"&gt;Watchman&lt;/a&gt;, also created by Facebook, which watches files, recording when they change. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a href="https://developer.apple.com/xcode/" rel="noopener noreferrer"&gt;XCode&lt;/a&gt;, Apple’s integrated development environment (IDE), which includes much needed debugging tools and iPhone simulators. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up a simulator in XCode, such as the simulator for the iPhone 16 Pro. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install XCode’s Command Line Tools to build and compile the app with xcodebuild, and manage the simulators, &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As for initializing the React Native application, I was going to see what GitHub CoPilot could come up with. &lt;/p&gt;

&lt;h2&gt;
  
  
  Composing the First Prompt
&lt;/h2&gt;

&lt;p&gt;After creating an empty folder called “detox-demo”, I entered a prompt in GitHub CoPilot chat describing the app I wanted to create: &lt;/p&gt;

&lt;p&gt;_"Create a React Native application for the iPhone that will be used to illustrate how to set up a Detox automation framework. The iOS app will be based on &lt;a href="https://the-internet.herokuapp.com/login" rel="noopener noreferrer"&gt;https://the-internet.herokuapp.com/login&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;"&lt;strong&gt;LoginPage&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"Heading: 'Login Page'. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Text: 'This is where you can log into the secure area. Enter tomsmith for the username and SuperSecretPassword! for the password. If the information is wrong you should see error message.' &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Username textbox. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Password textbox. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Login Button. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Incorrect login will produce a message in a red banner with white bolded text on the top of the screen: 'Your username is invalid!'. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Successful login goes to the SecureArea. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;“&lt;strong&gt;Secure Area&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"Heading: 'Secure Area'. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Body text: 'Welcome to the Secure Area. When you are done click logout below.'&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Successful login shows a green banner on top of screen with white bold text: 'You logged into a secure area!'. _&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Chaos Ensues
&lt;/h2&gt;

&lt;p&gt;After I submitted the GitHub CoPilot prompt, everything seemed okay, since it came back with a prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I'll help you create a React Native application for iOS. Let me
 break this down into steps
  1. First, I'll explore the workspace structure
  2. Create a React Native project
  3. Set up the Login and Secure Area screens

Let's start! [...] Since there is no specific template, I'll create
 the React Native project from scratch. Let me start by creating
 the basic project structure.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the chat logs, I caught a glimpse that it started initializing a new React Native project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @react-native-community/cli@latest init DetoxDemo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then things started going haywire.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It took three attempts to initialize a React Native project, first using what it kept claiming to be outdated methods. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instead of using the root directory, it created a sub-directory, placed the project code there, realized it had done that, then moved most of the project files back to root, forgetting to update much of the configurations. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since I mentioned the phrase “Detox” in my prompt, it then started work trying to initialize a Detox framework before building out the React Native application, and I wasn’t able to figure out how to correct its mistake. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;While attempting to create a Detox test framework, something must have interrupted the process when it used an outdated initialization command. It seemed surprised when it stumbled upon the Detox files it had already tried setting up, and had to study its own project it had attempted to put together. &lt;/p&gt;

&lt;p&gt;Only after many failed attempts, checks, rechecks, redos, did it finally realize that it never created the React Native application I had asked it to create.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Copilot has been working on this problem for a while. It can
 continue to iterate, or you can send a new message to refine
 your prompt.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Second Time Is The Charm?
&lt;/h2&gt;

&lt;p&gt;Seeing that there were problems, I then re-entered the prompt, trying again. &lt;/p&gt;

&lt;p&gt;Again, it had the same problems, investigating the project code it had written, re-creating the project in a new subdirectory, realizing it already had completed the work, then erasing the sub-directory. &lt;/p&gt;

&lt;p&gt;After that, it started printing a lot of text to the screen faster that I could read. According to the JSON file of the session, it was actually talking to itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The user has opened the workspace folder 
/Users/tj/src/detox-demo

Create a new project in this workspace folder.

To create a new project for the user, follow the steps below
 to create files, set up necessary extensions, and configure
 the project environment in Visual Studio Code.

Overview - 
- Call the tool get_project_setup_info to get a VS Code
 workspace-supported project template based on the user's
 request. 
- Run a command-line tool to scaffold the project files from
 a template.
- Create and update a copilot-instructions.md file in the
 project root under the .github directory.
- Customize the project files based on the user's requirements,
 if specified.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ah, no… I am not doing that. I would not know how to do any of that even if I tried. So, I just let GitHub CoPilot keep running. &lt;/p&gt;

&lt;p&gt;Again it tried creating a React Native application. &lt;/p&gt;

&lt;p&gt;Again it claimed it was using an outdated way to set up an application, reading the warnings that were being thrown as it was attempting to create the project. &lt;/p&gt;

&lt;p&gt;It decided it wanted to use a React Native project template that could not be found. &lt;/p&gt;

&lt;p&gt;On its second attempt, it downloaded, copied and processed a template, installing dependencies, updating my system to React Native 0.83.0. &lt;/p&gt;

&lt;p&gt;When it realized that I needed to install Cocoapods, it asked for permission. &lt;/p&gt;

&lt;p&gt;After that, it got caught in a loop where there was an error with npm that it had problems sorting out. &lt;/p&gt;

&lt;h2&gt;
  
  
  Third Time Is The Charm?
&lt;/h2&gt;

&lt;p&gt;Finally, it somehow fixed all of its errors, and progress was made. It got to the point I was looking for: &lt;/p&gt;

&lt;p&gt;Great! Now let me create the React Native screens. First, let me look at the current App.tsx: ,&lt;/p&gt;

&lt;p&gt;Now I'll replace the detox-demo with our login application. Let me also install react-navigation for navigation between screens:&lt;/p&gt;

&lt;p&gt;Now let me create the screens directory and LoginScreen component&lt;br&gt;
GitHub CoPilot then created: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;detox-demo/src/screens/LoginScreen.tsx&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;detox-demo/src/screens/SecureAreaScreen.tsx&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It added what it thought was appropriate testIDs to various screens, locators that test automation could use to find various React Native elements. &lt;/p&gt;

&lt;p&gt;Once it created a skeleton of the page, it started adding some meat on the bones.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Now let me create the SecureAreaScreen

Now let me update the App.tsx to use our new screens

I need to update the LoginScreen to handle the logout message. 

Let me fix that:

Let me add the logout message banner to the LoginScreen:

Now let me create a simple test to verify everything is working:

Let me fix the imports:

Now let me create the .github directory and copilot instructions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It created the app incrementally, adding piece by piece. After each piece was added, errors were thrown, then it had to fix those errors. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It kept losing track of the React-Navigation module. It kept forgetting where the module “detox” was. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It would define a new method, forget to use it, then delete it. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And it would edit the same few files again, and again, writing and rewriting so many times it was hard for me to keep track of what it was doing. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every few steps, it would run a linter, to see if anything went wrong, then fix it. All the while it acted as if it had amnesia from one step to the other, examining the directory, surprised that there was code already there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Perfect!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Now&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;me&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;make&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;we&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;can&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;iOS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;app.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;First,&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="err"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;me&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;pods:&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;I&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;see&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;there's&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;conflict&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;wrong&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;iOS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;directory.&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="err"&gt;Let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;me&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;update&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Detox&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;configuration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;correct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;paths:&lt;/span&gt;&lt;span class="w"&gt; 

&lt;/span&gt;&lt;span class="err"&gt;Let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;me&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;check&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;actual&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;project&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;structure&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Now&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;me&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;quick&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;see&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;our&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;app&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;builds&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;runs:&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;I&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;see&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;complex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;project&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;existing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;scripts.&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="err"&gt;Let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;me&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;look&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;correct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;again&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;understand&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="err"&gt;what&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;scripts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;we&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;actually&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;have:&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Good!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;We&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;have&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ios&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;script.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;issue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;seems&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;that&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="err"&gt;it's&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;running&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;different&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;project&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;context.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;me&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;with&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;correct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;working&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;directory:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;",

              "&lt;/span&gt;&lt;span class="err"&gt;toolCalls&lt;/span&gt;&lt;span class="s2"&gt;": [

There seems to be an issue with the package.json file. Let me 
check if it was corrupted or has any issues: "&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;

              &lt;/span&gt;&lt;span class="nl"&gt;"toolCalls"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub CoPilot kept continuing this way for quite some time until finally, it was finally finished. Finally.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Success! We Have An App!
&lt;/h2&gt;

&lt;p&gt;After what felt like hours, and after many failed attempts, GitHub CoPilot was finally finished. &lt;/p&gt;

&lt;p&gt;GitHub CoPilot set up in the DetoxDemo project in the package.json file some commands to build the Detox version of the app. I instructed GitHub CoPilot to use YARN instead of NPM as a Builder, like we use at SELF ID.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; To Build the Detox version of the app: yarn detox:build:ios&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I gave the command to build the app, launching an emulator, with the DetoxDemo icon ready to be clicked. &lt;/p&gt;

&lt;h2&gt;
  
  
  Adding the Automation
&lt;/h2&gt;

&lt;p&gt;I added automated tests for the React Mobile site in a folder I called “e2e” to store the end-to-end tests, written in Detox + TypeScript. &lt;/p&gt;

&lt;p&gt;To test the Login Flow, I fashioned the tests much like my first Selenium WebDriver + Java automation project, &lt;a href="https://www.tjmaher.com/2015/06/simple-manipulation-of-login-page.html" rel="noopener noreferrer"&gt;Testing The-Internet&lt;/a&gt;, written ten years before:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Login Page: Verify the expected Heading and Instruction text appear.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Login Page: Verify that invalid credentials displays the error message in a red banner at the top of the screen. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secure Area: Successful login displays a success message in a green banner at the top of the screen. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Documenting the Project Structure
&lt;/h2&gt;

&lt;p&gt;I then directed GitHub Copilot to create a README file showing the structure the code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;App source code in a “src” folder, with another folder marked “screens”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automated tests, written in Detox, in an “e2e” folder, with page objects in a folder “pages”. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitHub CoPilot then documented things like so in the DetoxDemo README file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── screens/
│   ├── LoginScreen.tsx       # Main login interface
│   └── SecureAreaScreen.tsx  # Secure area after login

e2e/
├── pages/
│   ├── base-page.ts          # Base page object with common methods
│   ├── login-page.ts         # Login screen page object  
│   └── secure-area-page.ts   # Secure area page object
├── constants.ts              # Time constants (2s, 3s, 5s, etc.)
├── credentials.ts            # Test credentials
├── init.ts                   # Detox initialization
├── jest.config.js           # Jest configuration for Detox
└── login.test.ts            # Main test suite

.detoxrc.js                  # Detox configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running the Automated Tests
&lt;/h2&gt;

&lt;p&gt;GitHub CoPilot set up in the &lt;a href="https://github.com/tjmaher/detox-demo" rel="noopener noreferrer"&gt;DetoxDemo project&lt;/a&gt; in the package.json file likewise some commands to test the Detox version of the app. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Open up a new Mac Terminal and started Metro: yarn start&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open up a second Mac Terminal to run the automated tests: yarn detox:test:ios&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I gave the command to test the app, it launched an emulator, opened up the &lt;strong&gt;DetoxDemo&lt;/strong&gt; app, and executed the tests. Once finished, Detox then printed the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login Flow: 
  ✓ Verify Heading and Instruction Text (1550 ms)
  ✓ Invalid credentials displays error message (3958 ms)
  ✓ Successful login to Secure Area displays success message (5159 ms)
  ✓ Logout from Secure Area returns to Login Page (5779 ms)

  Test Suites: 1 passed, 1 total
  Tests:       4 passed, 4 total
  Snapshots:   0 total
  Time:        27.516 s, estimated 39 s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Huzzah! The React Native app has been constructed and all the tests have passed! &lt;/p&gt;

&lt;p&gt;One task remained… an autopsy about what went wrong during this project. &lt;/p&gt;

&lt;p&gt;I fed the GitHub CoPilot chat log, stored as a JSON file after my GitHub CoPilot session, back into GitHub CoPilot, asking how things went so wrong. GitHub CoPilot then summarized everything that had gone wrong…&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary of GitHub Copilot's Mistakes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Wrong Project Creation Location
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Attempted to create the React Native project in the current directory using . as the target&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The CLI created a subdirectory in /Users/tj/src/DetoxDemo/ instead of using the intended workspace directory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Had to manually copy files from the wrong location to the correct workspace&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Incorrect React Native Initialization Commands
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First tried: npx react-native init DetoxDemo --template react-native-template-typescript . (failed)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then tried: npx @react-native-community/cli@latest init DetoxDemo --template react-native-template-typescript (failed)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally used: npx @react-native-community/cli@latest init DetoxDemo . which created files in the wrong location&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Created Expo Project Instead of Pure React Native
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The generated package.json showed it was an Expo-managed project&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The request was for a standard React Native application, not Expo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This mismatch would cause issues with Detox configuration&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Detox Installation Issues
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Attempted npm install --save-dev detox @config-plugins/detox which had dependency conflicts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Had to fall back to npm install --save-dev detox --legacy-peer-deps&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The @config-plugins/detox package was likely not needed&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Detox Initialization Problems
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Tried npx detox init -r jest but it failed because Detox files already existed in a parent directory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instead of resolving the conflict, manually created configuration files&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Typo in Page Object Request
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Class LogingPage extends BasePage (typo: "Loging" instead of "Login")&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copilot should have caught this obvious typo and corrected it&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7. Type System Issues
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mentioned needing to "fix the type issues in the base page"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Suggests TypeScript types weren't properly defined initially&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8. Over-Complicated Approach
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Used create_new_workspace tool unnecessarily&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Should have started with simpler file creation approach&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiple failed attempts before getting the basic structure right&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  9. "Cannot find module './package.json'" Error
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When attempting to run npm run ios, the React Native CLI failed:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This was because the node_modules were installed in the wrong location. The React Native binary expected to find files in a different structure.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  10. Wrong Diagnosis and Solution
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;After the module error, Copilot diagnosed it as a "dependency issue"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This was the wrong diagnosis - the issue wasn't corrupted dependencies but rather being in the wrong directory entirely.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  11. Port Conflict Error (EADDRINUSE)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This happened because Copilot tried to start the Metro bundler multiple times without killing previous instances.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  12. React Native 0.83.0 Build Failures
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The iOS build failed with C++ header redefinition errors&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copilot used React Native 0.83.0, which appears to be a bleeding-edge version with compilation bugs. Should have used a stable version like 0.81.x or 0.82.x.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  13. Detox Configuration File Errors
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Later in the session, attempts to read Detox config failed:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copilot created .detoxrc.js but then looked for .detoxrc.json and detox.config.js - inconsistent file naming.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  14. Unnecessary Reinstallations
&lt;/h3&gt;

&lt;p&gt;Rather than identifying the root cause (wrong directory), Copilot repeatedly tried:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reinstalling node_modules&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Editing configuration files&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Re-running failed commands&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modifying Detox config&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All while ignoring the core issue of working in the wrong workspace.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;As frustrating as it was acting as a passenger during GitHub CoPilot’s wild and madcap ride developing the DetoxDemo project, it all turned out well in the end.&lt;/p&gt;

&lt;p&gt;My first ReactNative application, DetoxDemo, has been created. I successfully added automated tests to the ReactNative mobile app. And now I have something to blog about. &lt;/p&gt;

&lt;p&gt;And, as I mentioned, feel free to use the DetoxDemo React Native app at &lt;a href="https://github.com/tjmaher/detox-demo" rel="noopener noreferrer"&gt;https://github.com/tjmaher/detox-demo&lt;/a&gt; if you need a React Native app to test against when practicing automation development. &lt;/p&gt;

&lt;p&gt;Because I stumbled on Dave Haefner's test site The-Internet, and all the rest of Dave's contributions to the software testing community, I became a better automation developer. I would like to return the favor. Thank you, Dave!  &lt;/p&gt;

&lt;p&gt;As always... Happy Testing! &lt;/p&gt;

&lt;p&gt;-T.J. Maher&lt;br&gt;
Software Engineer in Test&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.tjmaher.com/" rel="noopener noreferrer"&gt;Blog&lt;/a&gt; | &lt;a href="https://bsky.app/profile/tjmaher1.bsky.social" rel="noopener noreferrer"&gt;BlueSky&lt;/a&gt; | &lt;a href="http://bit.ly/tj_youtube" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.linkedin.com/in/tjmaher1" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; | &lt;a href="http://www.tjmaher.com/p/media.html" rel="noopener noreferrer"&gt;Articles&lt;/a&gt;&lt;/p&gt;

</description>
      <category>githubcopilot</category>
      <category>ai</category>
      <category>reactnative</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Investigating AI: Playwright-Test-Planner and Playwright-Test-Generator</title>
      <dc:creator>T.J. Maher</dc:creator>
      <pubDate>Tue, 17 Mar 2026 21:01:35 +0000</pubDate>
      <link>https://dev.to/tjmaher1/investigating-ai-playwright-test-planner-and-playwright-test-generator-455k</link>
      <guid>https://dev.to/tjmaher1/investigating-ai-playwright-test-planner-and-playwright-test-generator-455k</guid>
      <description>&lt;h2&gt;
  
  
  Testing Out Three New Playwright AI Tools
&lt;/h2&gt;

&lt;p&gt;The other day, I heard about three new Playwright AI tools that came out in October 2025. From the Playwright Test Agents docs:&lt;/p&gt;

&lt;p&gt;"Playwright comes with three Playwright Test Agents out of the box: 🎭 planner, 🎭 generator and 🎭 healer.&lt;br&gt;
These agents can be used independently, sequentially, or as chained calls in the agentic loop. Using them sequentially will produce test coverage for your product.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🎭 "planner — explores the app and produces a Markdown test plan&lt;/li&gt;
&lt;li&gt;🎭 "generator — transforms the Markdown plan into Playwright Test files&lt;/li&gt;
&lt;li&gt;🎭 "healer — executes the test suite and automatically repairs failing tests"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... So of course, I had to check it out! How well did they do? &lt;/p&gt;

&lt;p&gt;I found it fascinating that Playwright-test-planner could write a detailed test plan, one you could review and edit. And it was amazing that Playwright-test-generator could explore a website and find locators, and organize tests all on its own. &lt;/p&gt;

&lt;p&gt;The problem is that it did make incorrect assumptions when finding locators for common elements such as a "heading". When it logged into a login page, it thought the build in Playwright "heading" would have been enough to find the "Secure Area". Except the heading type was in an "h2" tag, so I had to tweak it a bit.&lt;/p&gt;

&lt;p&gt;All in all, it did well, getting me 80% there. If you want your automated test framework to store login credentials, or string messages in a separate data object, or store locators in private variables in page objects, you need to explicitly have prompts stating such. &lt;/p&gt;

&lt;p&gt;Out of the box, you aren't going to get the best solution. You still need a Senior SDET to guide the AI in building the automation framework. &lt;/p&gt;

&lt;p&gt;After all my experimentation with various coding AIs these past several months, I don't think they can replace SDETs, but they will save on a lot of typing! &lt;/p&gt;
&lt;h2&gt;
  
  
  Sidenote: Thank you, Butch Mayhew!
&lt;/h2&gt;

&lt;p&gt;If you ever really enjoy a course on LinkedIn Learning, reach out to the author. Butch Mayhew, Playwright Ambassador, referred me to two tools that came out in October 2025: playwright-test-planner and playwright-test-generator — Playwright test agents you can plug into GitHub Copilot.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;View Code&lt;/strong&gt;: &lt;a href="https://github.com/tjmaher/playwright-generate-plan" rel="noopener noreferrer"&gt;github.com/tjmaher/playwright-generate-plan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Need expert Playwright services? Butch has set up a shingle with &lt;a href="https://howdyqa.com/" rel="noopener noreferrer"&gt;Howdy QA&lt;/a&gt;: &lt;em&gt;"Save time and reduce testing costs with our expert Playwright automation services. From migration to training, we help you build a quality testing culture. From Zero to Automated with Playwright, Test Automation Health Audit, API Test Automation and Training &amp;amp; Education"&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Other Playwright resources from Butch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Book&lt;/strong&gt;: Hands-On Automated Testing with Playwright: Create fast, reliable, and scalable tests for modern web apps with Microsoft's automation framework &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn Learning Courses&lt;/strong&gt;: Learning Playwright  and Playwright Essential Training: Abstractions, Fixtures, and Complex Scenarios &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blog&lt;/strong&gt;: &lt;a href="https://playwrightsolutions.com/" rel="noopener noreferrer"&gt;https://playwrightsolutions.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Setting Up Windows 11:
&lt;/h2&gt;

&lt;p&gt;First, I created a new directory on my Windows 11 desktop at home. I tend to store source code of my projects in D:\src. With VS Code, I opened up a new Power Shell terminal, changed to the D:\src directory and made a new directory: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cd D:\src&lt;/li&gt;
&lt;li&gt;mkdir playwright-generate-plan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... then in VS Code I did File -&amp;gt; Open Folder and opened up the playwright-generate-plan directory I just created in D:\spec\playwright-generate-plan&lt;/p&gt;
&lt;h2&gt;
  
  
  Installing Playwright
&lt;/h2&gt;

&lt;p&gt;According to Playwright Docs / Intro all I had to do in the terminal was to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;npm init playwright@latest&lt;/li&gt;
&lt;li&gt;I selected the defaults of using TypeScript, place the end-to-end tests in "tests", and "Y" to create a GitHub Actions workflow, so I could create an eventual CI/CD pipeline. &lt;/li&gt;
&lt;li&gt;I chose it to install Chromium, Firefox, and Webkit (emulating Mac Safari) as the internal browsers. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After I installed it all, it printed out some helpful commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx playwright &lt;span class="nb"&gt;test
    &lt;/span&gt;Runs the end-to-end tests.

  npx playwright &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--ui&lt;/span&gt;
    Starts the interactive UI mode.

  npx playwright &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--project&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;chromium
    Runs the tests only on Desktop Chrome.

  npx playwright &lt;span class="nb"&gt;test &lt;/span&gt;example
    Runs the tests &lt;span class="k"&gt;in &lt;/span&gt;a specific file.

  npx playwright &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--debug&lt;/span&gt;
    Runs the tests &lt;span class="k"&gt;in &lt;/span&gt;debug mode.

  npx playwright codegen
    Auto generate tests with Codegen.

We suggest that you begin by typing:

    npx playwright &lt;span class="nb"&gt;test

&lt;/span&gt;And check out the following files:
  - .&lt;span class="se"&gt;\t&lt;/span&gt;ests&lt;span class="se"&gt;\e&lt;/span&gt;xample.spec.ts - Example end-to-end &lt;span class="nb"&gt;test&lt;/span&gt;
  - .&lt;span class="se"&gt;\p&lt;/span&gt;laywright.config.ts - Playwright Test configuration

Visit https://playwright.dev/docs/intro &lt;span class="k"&gt;for &lt;/span&gt;more information. 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Open GitHub Copilot and plan away!
&lt;/h2&gt;

&lt;p&gt;Opening up a new GitHub Copilot session, I selected from the dropdowns:&lt;br&gt;
Local&lt;br&gt;
playwright-test-planner&lt;br&gt;
GPT-4.1 (the free version that would not use up any tokens)&lt;/p&gt;

&lt;p&gt;... then I gave it the prompt...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Using Playwright and playwright-test-planner, outline positive
 and negative test cases for 
  https://the-internet.herokuapp.com/login

* Go to https://the-internet.herokuapp.com/login and check
 that the title is "Login Page". 

* Login as tomsmith / SuperSecretPassword!

* Once on Secure Area, select the Logout button and make sure
 that when back on the Login Page, that "You logged out of the
 secure area!" appears. 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, playwright-test (MCP server) went to work! &lt;/p&gt;

&lt;p&gt;Instead of having to approve every few seconds, I set it to "Always Allow" without needing to review.&lt;/p&gt;

&lt;p&gt;After a minute or two it came up with "login.plan.md". Not bad! &lt;/p&gt;

&lt;h2&gt;
  
  
  The Testplan is Auto-generated!
&lt;/h2&gt;




&lt;h2&gt;
  
  
  Login Page Test Plan
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Application Overview
&lt;/h2&gt;

&lt;p&gt;Test plan for the login functionality at &lt;a href="https://the-internet.herokuapp.com/login" rel="noopener noreferrer"&gt;https://the-internet.herokuapp.com/login&lt;/a&gt;, covering positive and negative scenarios including login, logout, and error handling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Login and Logout Functionality
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Seed:&lt;/strong&gt; &lt;code&gt;tests/seed.spec.ts&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  1.1. Positive Login and Logout Flow
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;File:&lt;/strong&gt; &lt;code&gt;tests/login-positive.spec.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;a href="https://the-internet.herokuapp.com/login" rel="noopener noreferrer"&gt;https://the-internet.herokuapp.com/login&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;expect: The page loads successfully.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Verify the visible heading is 'Login Page'

&lt;ul&gt;
&lt;li&gt;expect: The heading 'Login Page' is present.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Enter 'tomsmith' in the Username field

&lt;ul&gt;
&lt;li&gt;expect: Username field contains 'tomsmith'.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Enter 'SuperSecretPassword!' in the Password field

&lt;ul&gt;
&lt;li&gt;expect: Password field contains 'SuperSecretPassword!'.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click the Login button

&lt;ul&gt;
&lt;li&gt;expect: Redirected to the Secure Area page.&lt;/li&gt;
&lt;li&gt;expect: A message 'You logged into a secure area!' is displayed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click the Logout button

&lt;ul&gt;
&lt;li&gt;expect: Redirected back to the Login Page.&lt;/li&gt;
&lt;li&gt;expect: A message 'You logged out of the secure area!' is displayed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  1.2. Negative Login Scenarios
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;File:&lt;/strong&gt; &lt;code&gt;tests/login-negative.spec.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;a href="https://the-internet.herokuapp.com/login" rel="noopener noreferrer"&gt;https://the-internet.herokuapp.com/login&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;expect: The page loads successfully.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Enter invalid username 'wronguser' and invalid password 'wrongpass'

&lt;ul&gt;
&lt;li&gt;expect: An error message 'Your username is invalid!' is displayed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Leave both Username and Password fields blank and click Login

&lt;ul&gt;
&lt;li&gt;expect: An error message 'Your username is invalid!' is displayed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Generate the Tests
&lt;/h2&gt;

&lt;p&gt;Next, I switched the dropdown to "playwright-test-generator", and prompted it with:&lt;/p&gt;

&lt;p&gt;"Using Playwright + TypeScript and playwright-test-generator, generate the tests for specs/login.plan.md. Refactor locators into page objects, and common elements into a base page".&lt;/p&gt;

&lt;p&gt;It then came back with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"To implement your request, I will generate Playwright tests
 for both positive and negative login scenarios, refactoring
 locators into page objects and extracting common elements
 into a base page. No page object files currently exist, so I
 will create:

* BasePage (for shared elements/methods)

* LoginPage (for login form and actions)

* SecureAreaPage (for secure area and logout)

I will then generate the tests using these page objects.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It automatically generated page objects for base.page.ts,login.page.ts,and secure-area.page.ts in the tests/pages folder. &lt;/p&gt;

&lt;h2&gt;
  
  
  Minor Error Locating Secure Area Heading
&lt;/h2&gt;

&lt;p&gt;When I went to run the tests, though, the negative tests passed, but the "login-positive.spec.ts" tests failed, but since there were no screenshots, it was difficult to debug what was happening, so I asked GitHub Copilot to have playwright.config.ts turn video and screenshots to ON.&lt;/p&gt;

&lt;p&gt;It did have one small problem: It couldn't find the label "Secure Area".. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;this.heading = page.getByRole('heading', { name: 'Secure Area' });&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examining the page, it showed that the heading was actually an "h2" tag. Once I update it to    &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;this.heading = page.locator('h2')&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... everything worked out fine! &lt;/p&gt;

&lt;p&gt;What a quick way to stand up a simple project. Thank you, Butch for referring me to the tools! &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; View Code: &lt;a href="https://github.com/tjmaher/playwright-generate-plan" rel="noopener noreferrer"&gt;https://github.com/tjmaher/playwright-generate-plan&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy Testing!&lt;/p&gt;

&lt;p&gt;-T.J. Maher&lt;br&gt;
Software Engineer in Test&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.tjmaher.com/" rel="noopener noreferrer"&gt;Blog&lt;/a&gt; | &lt;a href="https://bsky.app/profile/tjmaher1.bsky.social" rel="noopener noreferrer"&gt;BlueSky&lt;/a&gt; | &lt;a href="http://bit.ly/tj_youtube" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt; | &lt;a href="https://www.linkedin.com/in/tjmaher1" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; | &lt;a href="http://www.tjmaher.com/p/media.html" rel="noopener noreferrer"&gt;Articles&lt;/a&gt;&lt;/p&gt;

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