<?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: Meta Luo</title>
    <description>The latest articles on DEV Community by Meta Luo (@metaluo).</description>
    <link>https://dev.to/metaluo</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%2F2228032%2Fba924d00-ba19-40b7-b19f-f3623be8f580.jpg</url>
      <title>DEV Community: Meta Luo</title>
      <link>https://dev.to/metaluo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/metaluo"/>
    <language>en</language>
    <item>
      <title>When AI Makes Coding Faster, Testing Matters More</title>
      <dc:creator>Meta Luo</dc:creator>
      <pubDate>Tue, 22 Sep 2026 07:05:29 +0000</pubDate>
      <link>https://dev.to/metaluo/when-ai-makes-coding-faster-testing-matters-more-2eln</link>
      <guid>https://dev.to/metaluo/when-ai-makes-coding-faster-testing-matters-more-2eln</guid>
      <description>&lt;p&gt;AI-assisted coding has changed the economics of a small product change.&lt;/p&gt;

&lt;p&gt;A form, a component, a UI refinement, or a thin API layer can now go from an idea to a working-looking implementation in minutes. That is useful. It also changes where delivery risk accumulates.&lt;/p&gt;

&lt;p&gt;The question used to be: &lt;em&gt;Can we build this fast enough?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Increasingly, it is: &lt;em&gt;How do we know that this change—and the flows around it—still work?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;AI can accelerate implementation. It cannot automatically understand every business rule, verify every state transition, or guarantee that a change to one page did not break another. As the cost of changing software falls, the cost of confidently validating those changes becomes more visible.&lt;/p&gt;

&lt;p&gt;That is why testing matters more in an AI-assisted workflow—not as a slower approval gate, but as the feedback system that makes speed safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fast code can make systems feel more opaque
&lt;/h2&gt;

&lt;p&gt;AI-generated code often looks plausible. Names are reasonable, components render, and comments read well. But production failures rarely come from code that merely looks untidy. They come from behavior that is subtly wrong:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an authorization rule is skipped on one path;&lt;/li&gt;
&lt;li&gt;a successful submission does not refresh the state that users see next;&lt;/li&gt;
&lt;li&gt;an edge-case input bypasses validation;&lt;/li&gt;
&lt;li&gt;a dependent field stops updating after a refactor;&lt;/li&gt;
&lt;li&gt;an existing workflow survives locally but fails for a different role or dataset.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code review still matters. Unit and integration tests still matter. But neither, by itself, proves that a user can complete a critical journey in the actual application.&lt;/p&gt;

&lt;p&gt;There is a second, quieter change. When a meaningful portion of an implementation starts as a prompt, completion, or agent-generated patch, engineers may spend less time constructing every detail from first principles. They should still review the change, of course. But the job shifts: less from writing each line, more toward evaluating whether a candidate solution is correct.&lt;/p&gt;

&lt;p&gt;That is not a criticism of AI coding. It is simply a reason to strengthen the feedback loops around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Faster UI changes expose weak regression habits
&lt;/h2&gt;

&lt;p&gt;Web products feel this first. If UI changes become cheaper, teams ship more of them: component swaps, layout changes, form reorganizations, dropdown behavior changes, and new client-side state. Small changes are individually reasonable; together, they expand the surface area for regression.&lt;/p&gt;

&lt;p&gt;Two existing approaches can struggle under that pace.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual regression does not scale with change frequency
&lt;/h3&gt;

&lt;p&gt;If development can produce several viable iterations in a day but validation still depends on a person clicking through the same release checklist, testing becomes the bottleneck. The outcome is not that testing is “too slow.” The confirmation method has simply not kept up with the rate of change.&lt;/p&gt;

&lt;p&gt;Manual exploration remains valuable for new behavior, ambiguous requirements, usability, and unexpected interactions. It is a poor long-term substitute for repeatedly checking the same stable business path before every release.&lt;/p&gt;

&lt;h3&gt;
  
  
  UI scripts can become a maintenance tax
&lt;/h3&gt;

&lt;p&gt;Playwright and Selenium are powerful tools. For teams with a maintained test framework, they offer control, integrations, and a great deal of flexibility.&lt;/p&gt;

&lt;p&gt;But UI tests are not free once they exist. Locators need discipline. Waits, fixtures, browser state, failures, traces, and page objects all require ownership. When teams accelerate front-end changes without improving their test contracts, the result is familiar: engineers spend more time repairing selectors than checking whether the business flow is correct.&lt;/p&gt;

&lt;p&gt;The answer is not to abandon scripted testing. It is to be deliberate about which layer owns which kind of confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reliable delivery needs two complementary controls
&lt;/h2&gt;

&lt;p&gt;Teams adopting AI coding usually need to improve two points in the loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before implementation: constrain the problem
&lt;/h3&gt;

&lt;p&gt;Before asking an AI tool to generate a significant change, clarify the behavior it must preserve and the behavior it must introduce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the user and role involved;&lt;/li&gt;
&lt;li&gt;state transitions and business rules;&lt;/li&gt;
&lt;li&gt;API or data constraints;&lt;/li&gt;
&lt;li&gt;error and empty states;&lt;/li&gt;
&lt;li&gt;acceptance criteria and regression risks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not ceremony for its own sake. A clear plan narrows the space in which an AI tool can make a confident but incorrect assumption. It also gives reviewers and testers a shared definition of what “done” means.&lt;/p&gt;

&lt;h3&gt;
  
  
  After implementation: verify the outcome
&lt;/h3&gt;

&lt;p&gt;No plan can replace execution. A test strategy must answer practical questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did the new behavior work for the intended user?&lt;/li&gt;
&lt;li&gt;Did the critical path that led here still work?&lt;/li&gt;
&lt;li&gt;Did the UI update after the operation completed?&lt;/li&gt;
&lt;li&gt;Does the feature behave correctly with realistic data and permissions?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Put simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AI helps generate an implementation faster. Testing verifies that the implementation delivers the intended behavior.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One cannot substitute for the other. A model that generated a feature may also help draft tests or analyze failures, but independent, repeatable checks remain essential—especially for the real browser, account state, and data that a user experiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a small, repeatable release path
&lt;/h2&gt;

&lt;p&gt;When a team realizes that testing is falling behind, the tempting reaction is to build a comprehensive automation program immediately. That often fails for the same reason a rushed AI-generated feature fails: the scope is too broad, and ownership is unclear.&lt;/p&gt;

&lt;p&gt;Start instead with a minimal release loop. For a typical internal web application, it might include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Login as a representative user (kept as a separate case).&lt;/li&gt;
&lt;li&gt;Create or submit one high-value business object.&lt;/li&gt;
&lt;li&gt;Verify that the object can be found and that its important state is correct.&lt;/li&gt;
&lt;li&gt;Exercise one configuration, approval, or permission-sensitive path.&lt;/li&gt;
&lt;li&gt;Run those cases as a short smoke suite before a release.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first success criterion is not “full coverage.” It is simpler: can the team rerun these paths reliably, and can a failed result show an unfamiliar engineer where the flow first diverged?&lt;/p&gt;

&lt;p&gt;That changes the conversation from “we need to automate everything” to “we need five important checks that we can trust.”&lt;/p&gt;

&lt;h2&gt;
  
  
  UI automation has to survive change, not just record it
&lt;/h2&gt;

&lt;p&gt;Record-and-replay tools, browser recorders, and generated test code all make it easier to capture a first version of a workflow. The harder question is what happens a month later, after several UI iterations.&lt;/p&gt;

&lt;p&gt;A useful UI automation asset should answer at least three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Can it run reliably under the same conditions?&lt;/li&gt;
&lt;li&gt;Can a small page change be repaired locally rather than forcing a full rewrite?&lt;/li&gt;
&lt;li&gt;When it fails, can the team understand the failure from the result rather than reconstructing the run from scratch?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those questions are more important than whether the first recording took two minutes or twenty.&lt;/p&gt;

&lt;p&gt;Good test design helps: stable test IDs, semantically meaningful labels, state-based waits, isolated data, and explicit assertions after important state changes. These are not merely automation details. They are contracts that make the product more observable and easier to evolve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where a record-and-replay platform fits
&lt;/h2&gt;

&lt;p&gt;There is a useful middle layer between “every regression path must be hand-tested” and “every UI check must start as a code project.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.icuecast.ai/" rel="noopener noreferrer"&gt;CueCast&lt;/a&gt; is designed for that layer: teams can record real browser interactions, store them as editable test steps, replay them, and keep results with screenshots for later review. It is a zero-code Web UI automation platform, not a replacement for API tests or an existing engineering-grade Playwright suite.&lt;/p&gt;

&lt;p&gt;For the workflows that are stable, business-critical, and repeatedly checked before releases, this model can reduce the cost of getting started and maintaining shared test assets. CueCast records multiple locator clues—including element semantics, text, component context, CSS, and XPath—rather than treating one brittle selector as the entire identity of an element. Playback uses a Chrome DevTools Protocol path for real browser interaction, with a DOM fallback for applicable cases.&lt;/p&gt;

&lt;p&gt;The important point is not that a tool makes UI automation magically permanent. No tool can infer a missing business distinction from an ambiguous page. When the product has two indistinguishable “Save” buttons, or an element has only runtime-generated attributes, the durable fix is still a better UI contract—such as a stable test ID, accessible label, or clear component scope.&lt;/p&gt;

&lt;p&gt;What a platform can do is make the maintenance loop visible: identify the failed step, review the screenshot and execution details, adjust a local step, replay the case, and then put it back into a scheduled regression plan.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Optional screenshot placeholder — recording-to-result workflow&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Use a redacted CueCast case detail or execution-result screen. Show an editable recorded step, a failure screenshot, and a concise error summary rather than a generic product dashboard.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Do not force every quality problem into UI replay
&lt;/h2&gt;

&lt;p&gt;UI regression is important, but it is not the whole test strategy. Keep the boundaries clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use unit tests for isolated logic and fast feedback.&lt;/li&gt;
&lt;li&gt;Use API or integration tests for contracts, complex fixtures, and backend state.&lt;/li&gt;
&lt;li&gt;Use browser-level regression for user-visible critical flows.&lt;/li&gt;
&lt;li&gt;Use exploratory testing to discover risks that predefined checks did not anticipate.&lt;/li&gt;
&lt;li&gt;Keep performance, security, accessibility, and data-quality work as dedicated disciplines rather than incidental side effects of UI tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Likewise, a team with a healthy Playwright or Selenium suite does not need to replace it in the name of AI adoption. A record-and-replay layer can coexist with code-based tests, particularly where business stakeholders or manual QA need to own and review high-frequency web flows.&lt;/p&gt;

&lt;p&gt;The goal is coverage with clear ownership, not one tool to solve every kind of quality risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing is becoming the speed multiplier
&lt;/h2&gt;

&lt;p&gt;AI coding is likely to keep reducing the time from idea to a running implementation. That does not automatically reduce release risk. If UI and workflow changes arrive faster while validation remains ad hoc, teams will either ship with less confidence or reintroduce manual checking as an expensive, late-stage ritual.&lt;/p&gt;

&lt;p&gt;The better response is not a heavier process. It is a tighter loop:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define the behavior and boundaries before implementation.&lt;/li&gt;
&lt;li&gt;Generate and review the change quickly.&lt;/li&gt;
&lt;li&gt;Run the most important repeatable checks against the real product.&lt;/li&gt;
&lt;li&gt;Treat failures as evidence to investigate, not prompts to retry blindly.&lt;/li&gt;
&lt;li&gt;Maintain the tests that protect high-value paths as the product evolves.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When implementation accelerates, testing becomes more—not less—valuable because it is what turns rapid output into reliable delivery.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>ai</category>
      <category>webdev</category>
      <category>automation</category>
    </item>
    <item>
      <title>AI Agents Are Great at Exploratory Testing. Regression Needs Repeatable Assets.</title>
      <dc:creator>Meta Luo</dc:creator>
      <pubDate>Thu, 17 Sep 2026 06:31:34 +0000</pubDate>
      <link>https://dev.to/metaluo/ai-agents-are-great-at-exploratory-testing-regression-needs-repeatable-assets-3ejg</link>
      <guid>https://dev.to/metaluo/ai-agents-are-great-at-exploratory-testing-regression-needs-repeatable-assets-3ejg</guid>
      <description>&lt;p&gt;AI agents have changed the first few minutes of testing a feature.&lt;/p&gt;

&lt;p&gt;Give an agent a goal such as “check whether a user can create a project,” and it can open the product, find a route into the flow, fill a form, react to a modal, and inspect the result. When it hits something unexpected, it can look at the page, source code, logs, or network activity and decide what to try next.&lt;/p&gt;

&lt;p&gt;That is genuinely useful. It is especially useful while a feature is new, ambiguous, or changing quickly.&lt;/p&gt;

&lt;p&gt;But it does not follow that a team should hand all regression testing to an agent. Exploratory testing and regression testing optimize for different things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exploration rewards judgment, adaptation, and trying an alternate path.&lt;/li&gt;
&lt;li&gt;Regression rewards the same path, the same checks, and evidence that makes one run comparable with the next.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The useful question is not “AI agent or test automation?” It is: &lt;strong&gt;which work should remain flexible, and which work is valuable enough to make repeatable?&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclosure: I work on CueCast, a no-code web regression-testing product. This article reflects the product problem we are building for, but the workflow below does not depend on using CueCast.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where agents are already excellent
&lt;/h2&gt;

&lt;p&gt;An AI agent is a strong partner when the testing task contains uncertainty.&lt;/p&gt;

&lt;p&gt;For example, after a developer finishes a new discount-rule screen, an agent can help answer questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can a user reach the new screen from the normal navigation?&lt;/li&gt;
&lt;li&gt;What happens with an empty, invalid, or unusually large input?&lt;/li&gt;
&lt;li&gt;Does an unexpected error appear in the browser console?&lt;/li&gt;
&lt;li&gt;Which conditions make a button enabled or disabled?&lt;/li&gt;
&lt;li&gt;Can the reported bug be reproduced from the current branch?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not always fully specified in advance. The agent can inspect the page, form a hypothesis, and alter its next action. It can also combine browser work with code and log inspection in a way that is awkward for a conventional UI test.&lt;/p&gt;

&lt;p&gt;That makes agents a practical fit for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;developer self-checks;&lt;/li&gt;
&lt;li&gt;exploratory testing of a new workflow;&lt;/li&gt;
&lt;li&gt;one-off reproduction of a reported bug;&lt;/li&gt;
&lt;li&gt;quick smoke checks when the test path is not yet known; and&lt;/li&gt;
&lt;li&gt;investigation after a failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The output of this work may be a useful conversation, screenshots, a list of observations, or a bug report. That can be enough when the task is temporary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a successful agent run is not yet a regression test
&lt;/h2&gt;

&lt;p&gt;Now consider a different request:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before every release, verify that an administrator can create a project, find it in the list, and see the correct status.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This request has to work next week, during the next release, and when a different teammate is on call. It needs a more explicit contract.&lt;/p&gt;

&lt;p&gt;An agent may still complete that workflow successfully today. However, unless the team deliberately captures the path and its checks, the next run may differ in meaningful ways. It might enter through a shortcut rather than the sidebar, accept a success toast as proof, or inspect the list only sometimes. Adaptive behavior is helpful during exploration; it makes a regression result harder to compare.&lt;/p&gt;

&lt;p&gt;Four things are usually missing when an agent run is treated as the entire test asset.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. A stable path
&lt;/h3&gt;

&lt;p&gt;Regression is not simply “the product looked OK.” It needs a known sequence of actions and preconditions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sign in as an administrator
  → create a project with unique data
  → save it
  → search for the saved project
  → verify its status is Draft
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The path does not have to be rigid forever. It does need to be visible, reviewable, and intentionally updated when product behavior changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Explicit assertions
&lt;/h3&gt;

&lt;p&gt;Navigation completing is not evidence that the workflow succeeded. A reliable test should say what must be true: the record exists, a status changed, a permission boundary holds, or an expected error is shown.&lt;/p&gt;

&lt;p&gt;Agents can suggest those checks, but the checks themselves should become named, inspectable assertions. Otherwise a passing result can quietly mean only that the agent reached a plausible-looking page.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Reusable test data and preconditions
&lt;/h3&gt;

&lt;p&gt;Many UI tests fail on their second run because they reuse a name such as &lt;code&gt;Test Customer&lt;/code&gt;, depend on an expired session, or assume a prior approval is still pending. A repeatable asset records how it gets the required state and how it avoids collisions—through generated values, variables, controlled fixtures, or a clear setup step.&lt;/p&gt;

&lt;p&gt;This is not glamorous test work, but it is what makes a release check trustworthy.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Evidence and ownership when a run fails
&lt;/h3&gt;

&lt;p&gt;“The agent could not complete the task” is the start of diagnosis, not the end of it. The next person needs to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which case and which step failed;&lt;/li&gt;
&lt;li&gt;what the page looked like at that point;&lt;/li&gt;
&lt;li&gt;what was expected and what was observed;&lt;/li&gt;
&lt;li&gt;whether the likely cause is the product, test data, environment, or a stale test; and&lt;/li&gt;
&lt;li&gt;who is responsible for the next action.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An agent can help interpret this evidence. The evidence should not disappear with the conversation that produced it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical handoff: explore, promote, replay
&lt;/h2&gt;

&lt;p&gt;Rather than choosing one approach for every situation, use a handoff between them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fby7mkb8e5swc6dklyloe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fby7mkb8e5swc6dklyloe.png" alt="Regression workflow" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Primary mode&lt;/th&gt;
&lt;th&gt;Deliverable&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A new feature or unclear requirement&lt;/td&gt;
&lt;td&gt;AI-assisted exploration&lt;/td&gt;
&lt;td&gt;Observations, risks, candidate paths, bug reports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A workflow becomes important and repeatable&lt;/td&gt;
&lt;td&gt;Test design and capture&lt;/td&gt;
&lt;td&gt;Named steps, assertions, test data rules, owner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Every release or relevant change&lt;/td&gt;
&lt;td&gt;Deterministic replay&lt;/td&gt;
&lt;td&gt;Pass/fail result, step-level evidence, history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A failure or a material UI change&lt;/td&gt;
&lt;td&gt;AI-assisted investigation&lt;/td&gt;
&lt;td&gt;Likely cause, update proposal, newly discovered risk&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The key moment is the middle one: promote a discovered workflow into a team asset once it is important enough to protect repeatedly.&lt;/p&gt;

&lt;p&gt;For example, an agent exploring a new project-creation flow may discover that the meaningful success condition is not the “saved” toast. It is that the new record appears in a filtered list with &lt;code&gt;Draft&lt;/code&gt; status and is visible only to administrators. That discovery becomes a regression case with three explicit assertions, unique data, and a saved execution history.&lt;/p&gt;

&lt;p&gt;The agent has not been replaced. It has done the higher-leverage job: finding uncertainty and helping the team decide what is worth protecting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What “repeatable” should mean in practice
&lt;/h2&gt;

&lt;p&gt;Repeatability does not mean pretending that a web application never changes. A healthy regression asset has enough structure to make change visible and enough context to repair it locally.&lt;/p&gt;

&lt;p&gt;For each high-value workflow, aim to keep:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A business-readable name.&lt;/strong&gt; “Administrator creates a draft project” is more useful than “case_014.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visible steps.&lt;/strong&gt; A teammate should be able to see the intended interaction rather than reverse-engineer it from a past chat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assertions at the business outcome.&lt;/strong&gt; Check the saved record, state, permission, or calculation—not just a click or URL change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A data strategy.&lt;/strong&gt; Define which values are generated, saved for later steps, reset, or provided by a fixture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failure evidence.&lt;/strong&gt; Keep the failing step, screenshot or page state, error, and relevant execution history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A maintenance owner.&lt;/strong&gt; Someone should be able to decide whether a change is a defect, a new requirement, or an asset update.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is also why “record once and forget it” is not a credible promise. User interfaces evolve. The goal is to avoid rewriting an entire workflow for a small, understandable change—and to make the affected step obvious when maintenance is necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where CueCast fits
&lt;/h2&gt;

&lt;p&gt;CueCast is designed for the repeatable part of this workflow: teams record actions on a real web application and turn them into editable steps, assertions, variables, and execution records. The product is aimed at recurring web business flows—such as sign-in, form submission, approval, configuration, and release smoke tests—where QA, developers, and business testers need to share the same test asset.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq5l408imp78ddfqhjwe4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq5l408imp78ddfqhjwe4.png" alt="CueCast screenshot" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is not intended to replace code-level tests, API tests, or free-form investigation. Complex data setup, deep mocking, and logic-heavy validation may still be best expressed in code. Likewise, an agent may be the best tool for a brand-new path that no one understands yet.&lt;/p&gt;

&lt;p&gt;The combination is more useful than either extreme:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI agent: explore the unknown and investigate changes
        ↓
Team: decide which workflows are release-critical
        ↓
Repeatable test asset: replay known steps and assertions
        ↓
AI agent: help interpret failures and identify the next risk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Start with five workflows, not a grand automation program
&lt;/h2&gt;

&lt;p&gt;If your team is experimenting with AI-assisted testing, do not begin by asking an agent to autonomously cover the whole product. Pick five workflows that are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run manually before almost every release;&lt;/li&gt;
&lt;li&gt;costly when they break;&lt;/li&gt;
&lt;li&gt;sufficiently stable to have a known expected outcome; and&lt;/li&gt;
&lt;li&gt;understandable by the people who own the business process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use agents to probe new behavior around those flows. Then give the recurring checks a durable home with explicit assertions, data rules, and evidence.&lt;/p&gt;

&lt;p&gt;That division of labor is simple: let AI spend its flexibility on change and uncertainty. Let repeatable assets protect the work your team already knows must not break.&lt;/p&gt;




&lt;p&gt;CueCast is an AI-assisted, no-code web automation tool for recording, replaying, and reviewing recurring regression workflows. Learn more at &lt;a href="https://www.icuecast.ai/" rel="noopener noreferrer"&gt;icuecast.ai&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>qualityassurance</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Sync Data from Elasticsearch to Elasticsearch</title>
      <dc:creator>Meta Luo</dc:creator>
      <pubDate>Sat, 09 May 2026 05:50:32 +0000</pubDate>
      <link>https://dev.to/metaluo/how-to-sync-data-from-elasticsearch-to-elasticsearch-16pp</link>
      <guid>https://dev.to/metaluo/how-to-sync-data-from-elasticsearch-to-elasticsearch-16pp</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Elasticsearch is a popular search engine that forms part of the modern data stack alongside relational databases, caching, real-time data warehouses, and message-oriented middleware.&lt;/p&gt;

&lt;p&gt;While writing data to Elasticsearch is relatively straightforward, real-time data synchronization can be more challenging.&lt;/p&gt;

&lt;p&gt;This article describes how to migrate and sync data from Elasticsearch to Elasticsearch using &lt;a href="https://www.bladepipe.com" rel="noopener noreferrer"&gt;BladePipe&lt;/a&gt; and the &lt;strong&gt;Elasticsearch incremental data capture plugin&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Highlights
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Elasticsearch Plugin
&lt;/h3&gt;

&lt;p&gt;Elasticsearch does not explicitly provide a method for real-time change data capture. However, its plugin API &lt;strong&gt;IndexingOperationListener&lt;/strong&gt; can track &lt;strong&gt;INDEX&lt;/strong&gt; and &lt;strong&gt;DELETE&lt;/strong&gt; events. The &lt;strong&gt;INDEX&lt;/strong&gt; event includes INSERT or UPDATE operations, while the &lt;strong&gt;DELETE&lt;/strong&gt; event refers to traditional DELETE operations.&lt;/p&gt;

&lt;p&gt;Once the mechanism for capturing incremental data is established, the next challenge is how to make this data available in downstream tools.&lt;/p&gt;

&lt;p&gt;We use a dedicated index, &lt;code&gt;cc_es_trigger_idx&lt;/code&gt;, as a container for incremental data.&lt;/p&gt;

&lt;p&gt;This approach has several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No dependency on third-party components (e.g., message-oriented middleware).&lt;/li&gt;
&lt;li&gt;Easy management of Elasticsearch indices.&lt;/li&gt;
&lt;li&gt;Consistency with the incremental data capture method of other BladePipe data sources, allowing for code reuse.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28c7dm6z1oxs0fi02odj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F28c7dm6z1oxs0fi02odj.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The structure of the &lt;code&gt;cc_es_trigger_idx&lt;/code&gt; index is as follows, where &lt;code&gt;row_data&lt;/code&gt; holds the data after the INDEX operations, and &lt;code&gt;pk&lt;/code&gt; stores the document &lt;strong&gt;_id&lt;/strong&gt;.&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mappings"&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;span class="nl"&gt;"_doc"&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;span class="nl"&gt;"properties"&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;span class="nl"&gt;"create_time"&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;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"date"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yyyy-MM-dd'T'HH:mm:ssSSS"&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;span class="nl"&gt;"event_type"&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;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"analyzer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"standard"&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;span class="nl"&gt;"idx_name"&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;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"analyzer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"standard"&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;span class="nl"&gt;"pk"&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;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"analyzer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"standard"&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;span class="nl"&gt;"row_data"&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;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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;span class="nl"&gt;"scn"&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;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"long"&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;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;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;h3&gt;
  
  
  Trigger Data Scanning
&lt;/h3&gt;

&lt;p&gt;As for the incremental data generated by using the Elasticsearch plugin, simply perform batch scanning in the order of the &lt;code&gt;scn&lt;/code&gt; field in the &lt;code&gt;cc_es_trigger_idx&lt;/code&gt; index to consume the data.&lt;/p&gt;

&lt;p&gt;The coding style for data consumption is consistent with that used for the SAP Hana as a Source.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open-source Plugin
&lt;/h3&gt;

&lt;p&gt;Elasticsearch strictly identifies third-party packages that plugins depend on. If there are conflicts or version mismatches with Elasticsearch's own dependencies, the plugin cannot be loaded. Therefore, the plugin must be compatible with the exact version of Elasticsearch, including the minor version.&lt;/p&gt;

&lt;p&gt;Given the impracticality of releasing numerous pre-compiled packages and to encourage widespread use, we place the open-source plugin on &lt;a href="https://github.com/ClouGence/cloudcanal-es-trigger" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Procedure
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Install the Plugin on Source Elasticsearch
&lt;/h3&gt;

&lt;p&gt;Follow the instructions in &lt;strong&gt;&lt;a href="https://www.bladepipe.com/docs/dataMigrationAndSync/datasource_func/ElasticSearch/prepare_for_es_as_src/" rel="noopener noreferrer"&gt;Preparation for Elasticsearch CDC&lt;/a&gt;&lt;/strong&gt; to install the incremental data capture plugin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Install BladePipe
&lt;/h3&gt;

&lt;p&gt;Follow the instructions in &lt;a href="https://www.bladepipe.com/docs/productOP/byoc/installation/install_worker_docker/" rel="noopener noreferrer"&gt;Install Worker (Docker)&lt;/a&gt; or &lt;a href="https://www.bladepipe.com/docs/productOP/byoc/installation/install_worker_binary/" rel="noopener noreferrer"&gt;Install Worker (Binary)&lt;/a&gt; to download and install a BladePipe Worker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Add DataSources
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Log in to the &lt;a href="https://cloud.bladepipe.com" rel="noopener noreferrer"&gt;BladePipe Cloud&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;DataSource&lt;/strong&gt; &amp;gt; &lt;strong&gt;Add DataSource&lt;/strong&gt;, and add 2 DataSources.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 4: Create a DataJob
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;DataJob&lt;/strong&gt; &amp;gt; &lt;a href="https://www.bladepipe.com/docs/operation/job_manage/create_job/create_full_incre_task/" rel="noopener noreferrer"&gt;&lt;strong&gt;Create DataJob&lt;/strong&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Select the source and target DataSources, and click &lt;strong&gt;Test Connection&lt;/strong&gt; to ensure the connection to the source and target DataSources are both successful.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Incremental&lt;/strong&gt; for DataJob Type, together with the &lt;strong&gt;Full Data&lt;/strong&gt; option.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
In the &lt;strong&gt;Specification&lt;/strong&gt; settings, make sure that you select a specification of at least &lt;strong&gt;1 GB&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Allocating too little memory may result in Out of Memory (OOM) errors during DataJob execution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Select the indices to be replicated.&lt;/li&gt;
&lt;li&gt;Select the fields to be replicated.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
If you need to select specific fields for synchronization, you can first create the index on the target Elasticsearch instance. This allows you to define the schemas and fields that you want to synchronize.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Confirm the DataJob creation.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
The DataJob creation process involves several steps. Click &lt;strong&gt;Sync Settings&lt;/strong&gt; &amp;gt; &lt;a href="https://www.bladepipe.com/docs/operation/job_setting/console_job_manage/" rel="noopener noreferrer"&gt;&lt;strong&gt;ConsoleJob&lt;/strong&gt;&lt;/a&gt;, find the DataJob creation record, and click &lt;strong&gt;Details&lt;/strong&gt; to view it.&lt;/p&gt;

&lt;p&gt;The DataJob creation with a source Elasticsearch instance includes the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Schema Migration&lt;/li&gt;
&lt;li&gt;Initialization of Elasticsearch Triggers and Offsets&lt;/li&gt;
&lt;li&gt;Allocation of DataJobs to BladePipe Workers&lt;/li&gt;
&lt;li&gt;Creation of DataJob FSM (Finite State Machine)&lt;/li&gt;
&lt;li&gt;Completion of DataJob Creation&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Wait for the DataJob to automatically run.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
Once the DataJob is created and started, BladePipe will automatically run the following DataTasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Schema Migration&lt;/strong&gt;: The index mapping definition in the source Elasticsearch instance will be migrated to the Target. If an index with the same name already exists in the Target, it will be ignored.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full Data Migration&lt;/strong&gt;: All existing data in the Source will be fully migrated to the Target.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incremental Synchronization&lt;/strong&gt;: Ongoing data changes will be continuously synchronized to the target instance.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

</description>
      <category>elasticsearch</category>
      <category>database</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
