Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,4 +297,9 @@ Program](https://bughunters.google.com/open-source-security).

## License

Apache 2.0 — see [LICENSE](LICENSE) for details.
Apache 2.0 — see [LICENSE](LICENSE) for details.
## Examples

Check out the [examples/](examples/) directory for practical guides on integrating Stitch:

- **CI Visual Testing** (`ci-visual-testing/`): Shows how to integrate Stitch into a CI pipeline for visual diffs and screenshot baseline evaluation.
26 changes: 26 additions & 0 deletions packages/sdk/examples/ci-visual-testing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# CI Visual Testing Example

This example demonstrates how to integrate the Stitch SDK into a Continuous Integration (CI) pipeline to automatically regenerate UI designs and perform visual testing against baseline screenshots.

## Overview

Visual regression testing is crucial for ensuring that code changes do not inadvertently break the user interface. This example shows how to use Stitch to:

1. Regenerate a design in a CI environment.
2. Capture the updated screenshot URL provided by the Stitch SDK.
3. Compare the new screenshot against a known baseline to detect visual differences.

## Structure

- **`SKILL.md`**: Instructions for an agent on how to set up and run the visual testing workflow.
- **`scripts/ci-runner.ts`**: The actual TypeScript script that runs the regeneration and comparison logic.

## Running the Example

1. Ensure your `STITCH_API_KEY` is set in your environment.
2. Provide a valid `PROJECT_ID` and `SCREEN_ID` in the script.
3. Run the script:

```bash
bun scripts/ci-runner.ts
```
38 changes: 38 additions & 0 deletions packages/sdk/examples/ci-visual-testing/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Skill: CI Visual Testing with Stitch SDK

## Context

Visual testing in CI ensures that UI designs remain consistent. The Stitch SDK generates UI screens and provides direct access to screenshot URLs via a content delivery network (CDN). This skill teaches an agent how to evaluate visual diffs from these screenshot URLs to determine if a design regression has occurred.

## Objective

The goal is to automate the visual verification of UI components in a CI pipeline using the `@google/stitch-sdk`.

## Workflow

1. **Regenerate Design**: Fetch the latest configuration or prompt and regenerate the screen using the Stitch SDK.
2. **Fetch Screenshot**: Obtain the screenshot URL using `screen.getImage()`.
3. **Visual Evaluation**: The agent should fetch the image from the URL and compare it against a baseline image.
- _Note_: Since direct pixel-by-pixel comparison might be complex in this specific script, the agent should simulate or use a mock visual comparison logic, or output the URLs for manual or external tool review.
4. **Reporting**: Output the status (Pass/Fail) based on the visual comparison.

## Example Script Structure

The script `scripts/ci-runner.ts` provides a starting point for this workflow.

```typescript
import { stitch } from "@google/stitch-sdk";

// 1. Fetch project and screen
// 2. Obtain current image URL
// 3. Compare with baseline (mock implementation provided in script)
```

## Agent Evaluation Guidelines

When evaluating the visual diff, consider:

- Are the core layout structures identical?
- Are the primary brand colors maintained?
- Is the typography consistent?
- _Crucially_, the agent must recognize that `getImage()` returns a URL, not the raw image bytes.
80 changes: 80 additions & 0 deletions packages/sdk/examples/ci-visual-testing/scripts/ci-runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { stitch } from "@google/stitch-sdk";
import "../../_require-key.js";

async function runVisualTests() {
console.log("Starting CI Visual Testing Workflow...\n");

// Fetch accessible projects to find a sample screen
const projects = await stitch.projects();
if (projects.length === 0) {
console.error("No projects found. Cannot run visual tests.");
return;
}

const project = projects[0];
console.log(`Using Project ID: ${project.id}`);

const screens = await project.screens();
if (screens.length === 0) {
console.error(`No screens found in project ${project.id}.`);
return;
}

const screen = screens[0];
console.log(`Base Screen ID: ${screen.id}`);

// Regenerate design
console.log("Regenerating design...");
const regeneratedScreen = await screen.edit(
"Ensure standard layout and branding is applied",
);
console.log(`Regenerated Screen ID: ${regeneratedScreen.id}`);

// Fetch the current screenshot URL from Stitch
let currentImageUrl;
try {
currentImageUrl = await regeneratedScreen.getImage();
console.log(
`Current Image URL obtained: ${currentImageUrl?.slice(0, 80)}...`,
);
} catch (error) {
console.error("Failed to obtain current image URL.", error);
return;
}

// Define a mock baseline image URL for demonstration purposes
const baselineImageUrl =
"https://lh3.googleusercontent.com/mock-baseline-image-url";

console.log(`Baseline Image URL: ${baselineImageUrl?.slice(0, 80)}...`);

// Simulate Visual Diffing Logic
console.log("\n--- Visual Diff Evaluation ---");
console.log("Downloading current image...");
console.log("Downloading baseline image...");
console.log("Comparing pixels...");

// Mock evaluation logic
const isMatch = Math.random() > 0.2; // 80% chance of passing

if (isMatch) {
console.log(
"✅ Visual Test Passed: The current design matches the baseline.",
);
} else {
console.log(
"❌ Visual Test Failed: Significant visual differences detected.",
);
console.error(
"Regression detected. Please review the visual diff artifacts.",
);
// In a real CI environment, you would exit with a non-zero status code here
// process.exit(1);
}
}

// Execute the workflow
runVisualTests().catch((err) => {
console.error("Unexpected error during visual testing:", err);
process.exit(1);
});
Loading