Seven short tutorials, in bullet points, with diagrams for every concept. Prep for interviews with NotebookLM, tell a prompt from a skill from an agent, learn RAG from scratch, drive the Playwright Agent CLI, understand why LLM evaluation is now a QA job, work safely in Cursor, and build your own skill directory you can reuse forever.
NotebookLM prepPrompt vs skill vs agentRAG basicsPlaywright CLILLM evaluationCursorSkill directory
NotebookLM is Google's source-grounded research notebook, powered by Gemini: it answers only from the sources you upload and cites them back. For interview prep that means answers built from your own resume, the real job description, and your project notes, not a chatbot's best guess.
What NotebookLM is and why grounding wins
Grounded by design. It answers only from the sources you upload, with citations back to each one, so there is far less invention than a raw chatbot.
Takes the files you already have. PDFs, Google Docs, websites, audio, images, and Sheets all work as sources.
Studio outputs are one click each. Audio Overview (a two-voice discussion of your sources), Video Overview (a narrated animated walkthrough), Mind Map (a visual hierarchy of topics), study guides, flashcards, quizzes, slide decks, infographics, and data tables.
Audio Overview comes in formats. Deep Dive, The Brief, The Critique, and The Debate: pick depth for a study session or speed before the call.
The free tier covers interview prep. The limits table below shows exactly what you get: plan each day's generation around it.
Every answer cites your own material, not the model's memory
Build your interview notebook
Create one notebook per interview target. One company, one notebook: a focused source set keeps every answer about that role.
Load QA-specific sources. Add the job description, the company engineering blog, your own resume, your project notes, and the STLC or testing docs you keep forgetting.
Interrogate it in chat. Ask "which of my projects best matches the automation requirement in this JD" and follow the citations back to your own notes.
Generate flashcards and a quiz. Flashcards for definitions (severity vs priority, regression vs retesting), then a quiz to self-test cold before the call.
Generate a Mind Map to see gaps. Thin branches are the topics your sources barely cover: revise those first.
Finish with an Audio Overview for commute revision. You get 3 per day on the free tier, so generate it after your source list is final: Deep Dive for full coverage, The Brief for a fast refresher.
One notebook per interview target, five moves from sources to revision
Keep it honest. NotebookLM will not invent experience you do not have: use it to recall and structure what you actually did, never to fake projects, because every claim gets a follow-up question in the room.
Free tier limit
What you get
Notebooks
100 per account
Sources
50 per notebook
Chat queries
50 per day
Audio Overviews
3 per day
Video Overviews and Deep Research
Limited
Answering only from your own documents is the same idea RAG is built on: when you are ready to apply it to test generation, read the RAG tutorial for QA.
A prompt is what you type, a skill is what you save, an AI agent is the system that uses both. Knowing which rung you are on decides whether your AI testing work is a one-off or an asset your whole team reuses.
The ladder: prompt -> skill -> agent
Prompt: typed every time. Instructions that live in your head or a notes file, with zero reuse guarantee.
Vibe-coded prompt: iterated, still disposable. A longer prompt you refine until it works, but it is still typed per session and dies with the chat.
Skill: a folder the agent loads on demand. A SKILL.md with YAML frontmatter (name plus description) and Markdown instructions: reusable, shareable, version controlled.
AI agent: the loop that uses both. A system that plans, calls tools, observes results, and loops until the goal is met.
Each rung reuses the one below. A skill packages a proven prompt; an agent loads skills while it works: that is the whole ladder.
Each rung reuses the one below it
Promote a prompt into a skill
Catch the repeat. The third time you type the same test-case prompt, stop: anything retyped is a skill candidate.
Create the folder. Make a directory with a SKILL.md inside: YAML frontmatter on top, instructions below.
Write the description for matching. The agent loads a skill only when the description matches the request, so name the exact situations it should fire in.
Move the prompt body into the Markdown section. Your proven wording becomes the instructions the agent follows.
Commit it to git. Now it is version controlled: reviewable in a pull request and shareable with the whole team.
Let the agent drive. On a matching request the agent plans, calls tools, observes results, and loops until the goal is met, with your skill guiding it.
---
name: qa-test-case-writer
description: Generate test cases from a user story or requirement.
Use when asked to write, expand, or review test cases.
---
Write test cases in Given/When/Then form.
Always cover happy path, negative, and boundary cases.
The agent loop, powered by your prompts and skills
Description is the trigger. A skill loads only when its description matches the request, so write it with the words a teammate would actually type: "write test cases", "review test cases", not clever prose.
RAG stops you from hoping the model memorised your product: it retrieves chunks from your own documents and pastes them into the prompt as context. For a tester, that is the difference between a test case you can trace to a spec and a confident guess you cannot.
What RAG actually is
RAG in one line. Retrieval Augmented Generation: instead of trusting whatever the model memorised in training, you retrieve the most relevant chunks from your own documents and hand them to the model as context for its answer.
Embeddings are the engine. An embedding turns text into a vector of numbers so that similar meanings sit close together. Retrieval is then a similarity search over those vectors: matching by meaning, not by keyword.
Chunking is a tuning knob. Documents are split into pieces before embedding. Too big and retrieval gets noisy, too small and the context is lost. Getting this wrong is the most common reason a RAG setup feels dumb.
Grounding makes hallucinations checkable. If an answer cites no retrieved chunk, it is unsupported. That one rule turns "sounds right" into something you can actually verify.
The QA payoff. Ground test generation in your real specs, past bug reports, and requirements, so every generated case traces back to a real source instead of a guess.
The answer is generated only from retrieved chunks, so every claim has a source
Build your first QA RAG, step by step
Collect your sources. Gather the documents that define what correct looks like: specs, requirements, past bug reports. This is the ingest stage.
Chunk them. Split each document into passages: small enough to be specific, big enough to keep their meaning intact.
Embed every chunk. Run each chunk through an embedding model to get a vector of numbers. Similar meanings land close together in that vector space.
Store the vectors. Load them into a vector database so they can be searched by similarity later.
Ask and retrieve. Embed your question the same way, then retrieve the top matching chunks for it.
Generate with receipts. Paste the retrieved chunks into the prompt and instruct the model to answer only from them, citing which chunk supports each claim.
SPEC CHUNK (retrieved from checkout-spec, section 4.2):
"An invalid promo code shows error PROMO-401 and
leaves the cart total unchanged."
QA QUESTION:
"What should happen when a user applies an invalid promo code?"
GROUNDED ANSWER:
Show error PROMO-401 and keep the cart total unchanged.
Source: checkout-spec, section 4.2.
DERIVED TEST CASE:
1. Add any item to the cart
2. Apply an invalid promo code
3. Assert error PROMO-401 is displayed
4. Assert the cart total did not change
Without RAG you get confidence, with RAG you get evidence
Trust rule. If the answer cites no chunk, it is unsupported. Treat an uncited claim from your RAG assistant like an untested code path: do not build a test case on it until you find the source it came from.
The Playwright Agent CLI puts a real browser at the end of your terminal, built so an AI agent can drive it without drowning in raw HTML. Sessions, network inspection, route mocking, and tracing all live behind one binary: playwright-cli.
Why agents love this CLI
What it is. A command line front end to a real browser: open pages, inspect network traffic, mock or block requests, and record traces without writing a test file first.
Token-efficient by design. An agent does not need the whole page, it needs just enough structure to act. The CLI is built around that idea, which keeps agent runs cheap and fast.
Ref-based snapshots. Instead of dumping raw HTML, the CLI returns a snapshot where each element carries a ref. The agent acts on the ref directly and never reads the whole DOM.
Named isolated sessions. A flag like -s=cart gives a flow its own isolated session, so your cart experiment and your login experiment never share state.
Skills for your agent. One command, playwright-cli install --skills, installs the skill set an agent can call to drive the browser on its own.
The CLI hands the agent refs, not the whole page
Hands-on: your first session
Install once. Run npm install -g @playwright/cli. This provides the playwright-cli binary.
Check your setup. Print the resolved config with playwright-cli config so surprises surface now, not mid-run.
Open a named session. Start a headed, isolated session against the practice cart: playwright-cli -s=cart open https://app.thetestingacademy.com/playwright/ttacart/ --headed.
Watch the wire. Inspect what the page is calling with playwright-cli network, then mock or block the API layer with playwright-cli route "**/api/**".
Record the evidence. Run playwright-cli tracing-start, drive the flow, then save it with playwright-cli tracing-stop trace.zip.
Review and extend. Open the dashboard with playwright-cli show, and hand your agent the toolkit with playwright-cli install --skills.
npm install -g @playwright/cli
playwright-cli config
playwright-cli -s=cart open https://app.thetestingacademy.com/playwright/ttacart/ --headed
playwright-cli network
playwright-cli route "**/api/**"
playwright-cli tracing-start
# drive the flow in the browser
playwright-cli tracing-stop trace.zip
playwright-cli show
playwright-cli install --skills
The debug loop: record, replay, fix, repeat
Tracing is not retroactive. The trace only contains what happened after playwright-cli tracing-start. If the bug already happened, start tracing first, reproduce the flow again, then run playwright-cli tracing-stop trace.zip to capture it.
Every command above comes straight from the full walkthrough at /masterclass/playwright-cli: start there when you are ready to wire the CLI into a real agent workflow.
Your product just shipped a feature that writes its own output. assertEquals cannot grade a paragraph, so if you want to be the tester who signs off AI features, you need a new kind of assertion: the metric.
Why assertEquals cannot grade a paragraph
Same input, different valid outputs. An LLM feature is non-deterministic by design. There is no single expected string, so there is nothing for assertEquals to pin.
String equality grades characters, not meaning. Two answers can share zero words and both be right, or match closely and be subtly wrong. Equality fails the first and passes the second: the exact opposite of what you want.
A metric is the replacement. It measures one property of the output (relevancy, faithfulness, toxicity) and returns a score from 0 to 1. Evaluation replaces equality with measurement.
The threshold is yours. You compare the score against a threshold you own, and that comparison is a deterministic pass or fail your pipeline understands.
Direction matters. Quality metrics treat the threshold as a floor: higher is better. Safety metrics treat it as a ceiling: lower is better. Confuse the two and toxic output passes.
Equality grades characters, a metric measures a property against your threshold
The judge loop: your first eval
Capture a real test case. Save the input, the retrieved context if the feature uses RAG, and the exact output the model produced.
Pick one metric and its direction. Quality metrics like answer relevancy or faithfulness need a floor; safety metrics like hallucination or PII leakage need a ceiling.
Choose a judge that is not the model under test. LLM-as-judge means a second, trusted model does the grading. The grader and the graded are never the same model, no exceptions.
Score and collect the reason. The judge returns a score from 0 to 1 plus a written reason, so a failure tells you why it failed, not just that it failed.
Assert against your threshold. DeepEval is pytest-native, so a metric that misses its threshold fails the build like any red test. PromptFoo and TruLens are the other two tools to know.
Rerun on every change. New prompt, new model, new context source: run the suite again. That is regression testing for a feature that writes its own output.
The grader and the graded are never the same model
Start with two metrics. Faithfulness with a floor and hallucination with a ceiling catch most early failures. Keep every threshold in version control: a sign-off you cannot diff is not a sign-off.
Evaluation is the only way to regression-test a feature that grades differently every run, and the tester who owns the metrics and thresholds is the one who signs off the AI feature. The full pytest setup, metric by metric, is in the DeepEval masterclass.
Cursor is an AI-first code editor, and for QA its value is bounded, reviewable agent work on your test repo. The discipline is short: rules first, one small task, deterministic verification before you accept a single diff.
The workflow: constrain before you trust
Treat the agent like a fast junior. It is quick and confident, and it needs what a new hire needs: written conventions, a small first ticket, and a reviewer who actually runs the code.
Privacy-aware setup comes first. Decide what the editor may see and send before pointing it at a work repo. Nothing else matters if that answer is wrong.
Rules beat prompts. A prompt steers one task, a project rule constrains every task: locator policy, naming, paths the agent must not touch, written once.
Small scope is the safety feature. One spec, one page object, one fixture per task. Small tasks produce small diffs, and small diffs are the only ones you can genuinely review.
Deterministic verification is the gate. The agent's summary is not evidence. The suite passing is. Run it before you accept anything.
Green accepts the diff, red re-scopes the task, repeat mistakes become new rules
One bounded task, end to end
Write project rules. Capture repo conventions as rules the agent must follow: selector strategy, folder layout, files that are off limits.
Scope one small task. "Add a spec for the empty cart state" beats "improve coverage". If you cannot predict the shape of the diff, shrink the task.
Pick the least-autonomous agent mode that works. Bounded agent modes exist so you choose the leash length: the goal is a proposed diff you review, not silent edits.
Feed context deliberately. Use MCP when the task needs tools or data beyond the repo, and target your Playwright assets so the output lands in code your suite can check.
Verify before accepting. Read the diff, then run the suite. Green is the acceptance gate. Red means reject or re-scope, never "accept and fix later".
Add the second net. Use CLI review to inspect the work, let Bugbot run an automated review pass, and fold any repeated mistake into a new rule.
Different surfaces, same gate: the suite must pass before you accept
Piece
What it does for a tester
Project rules
Standing constraints applied to every task: your conventions in, your forbidden paths out
Bounded agent modes
Cap how much the agent may change on its own, so the output is a proposed diff, not a surprise merge
Playwright assets
Point the agent at real test code, specs, page objects, fixtures, so your existing suite can verify its work
MCP
Connects the agent to tools and data beyond the repo, so context comes from real systems instead of guesses
CLI review
Inspect the agent's work from the command line before anything lands
Bugbot
Automated review pass over changes: a second reader, never a substitute for running the suite
Golden rule. If you cannot verify a diff by running the suite, the task was scoped too big: split it and go again. Never accept on the agent's word alone.
The full setup, from privacy-aware configuration to Bugbot, is in the Cursor masterclass, with the field lessons collected in the follow-up.
A skill directory is your personal library of SKILL.md folders: versioned in git, discovered by your agent, loaded only when a request matches. Prompts scattered across notes files die with the session; a directory gets reviewed, shared, and pulled like code.
A versioned library, not a pile of prompts
One skill, one folder. Each skill is a folder holding a SKILL.md: YAML frontmatter with a name and a description, then Markdown instructions. The directory is simply your collection of those folders under version control.
Progressive disclosure keeps it cheap. Only the name and description sit in context at all times, about 100 tokens. The body loads when a request matches the description, and referenced files load only when a step needs them. That is why dozens of skills stay cheap.
Reuse across projects. A prompt you retype is a prompt you mutate. A skill in ~/.claude/skills/ follows you into every repo, identical every time.
Review in pull requests. A SKILL.md change ships through the same PR flow as code: diffed, commented, approved. A prompt in a notes file gets none of that.
Distribution by git pull. Commit the folder once and every teammate inherits the whole library on their next pull. No pasted prompts in chat, no "which version do you have".
Portability across agents. Claude Code, GitHub Copilot, and Hermes all discover skills from folders, and VS Code Copilot reads .claude/skills/ too, so one repo folder can serve two agents.
Progressive disclosure: dozens of skills cost almost nothing until one matches
Build and ship your first skill
Create the folder. In your test repo run mkdir -p .claude/skills/flaky-test-triage: one folder per skill, named after the job it does.
Write the frontmatter. Add a SKILL.md whose description carries the exact trigger phrases teammates type, like "flaky test" or "quarantine this spec". The agent matches requests against this text, so a vague description never fires.
Keep the body small. Below the frontmatter, write short Markdown steps with exact commands and expected output. The body only loads on a match, and a tight body keeps the loaded context sharp.
Split out heavy parts only when needed. Move long checklists into references/ and helper code into scripts/. They load only when a step points at them.
Commit it. Run git add .claude/skills/ && git commit: the skill now has history, blame, and a reviewable diff.
Let the team pull it. Teammates run git pull and their agent discovers the new skill automatically. Shipping a capability becomes a one-line changelog entry.
.claude/skills/
└── flaky-test-triage/
├── SKILL.md
├── references/
│ └── quarantine-checklist.md
└── scripts/
└── rerun-failed.sh
# SKILL.md
---
name: flaky-test-triage
description: Triage a flaky Playwright test. Use when the user
says "flaky test", "quarantine this spec", "passes on retry",
or pastes an intermittent CI failure.
---
## Steps
1. Re-run the failing spec alone, then with the full suite.
2. Compare the failing trace against the last green run.
3. Quarantine with an owner and a ticket, never silently.
Distribution is just version control: one commit turns a private trick into a team capability
Agent
Discovery locations
What that means
Claude Code
~/.claude/skills/ (personal) and .claude/skills/ (repo)
Global library plus per-repo skills
GitHub Copilot
.github/skills/ (repo) and ~/.copilot/skills/ (personal)
Same pattern, Copilot's own paths
VS Code Copilot
also reads .claude/skills/
One committed folder serves both agents
Hermes
~/.hermes/skills/
Your library travels across agents
The interop win: one committed folder can serve both agents
Write the description like a matching rule. The description is the only part the agent always sees, so front-load the phrases a teammate would actually type and name the artifacts involved (spec, trace, CI log). If a skill never fires, fix the description before touching the body.
Do not start from zero: our ready-made 36-skill QA suite covers the STLC end to end and drops straight into your directory. Grab it at /masterclass/skill-masterclass.