Mockery: fake web scenarios for real Ferret tests.
Mockery is a deterministic static website used as a safe playground for Ferret, HTML drivers, docs examples, blog posts, and Lab scenarios.
It is organized around scenarios. A scenario is a controlled fake web situation designed to test or demonstrate a specific scraping or browser behavior: static extraction, product listings, pagination, forms, tables, network activity, infinite scroll, delayed rendering, iframes, messy markup, shadow DOM, and navigation interactions.
src/pages/Astro routes and static JSON/SVG endpointssrc/layouts/shared page shellsrc/components/reusable scenario and product UIsrc/data/deterministic fixtures to maintainsrc/assets/shared CSS and vanilla browser scriptsscripts/deterministic fixture generation helpersexamples/ferret/readable Ferret example scriptstests/validate-dist.test.mjsstatic output validationdist/generated static output
The project intentionally uses Astro conventions instead of a custom static
site generator. Most maintenance should be content changes in src/data/ and
scenario page copy.
Generated under /scenarios/:
/scenarios/ecommerce//scenarios/dynamic-products//scenarios/network//scenarios/messy-markup//scenarios/forms//scenarios/tables//scenarios/infinite-scroll//scenarios/delayed-rendering//scenarios/shadow-dom//scenarios/iframes//scenarios/navigation/
npm install
npm run devBuild and preview the generated static site:
npm run build
npm run previewpreview serves the generated dist/ directory with Astro.
Mockery output is fully static and can be deployed as-is from dist/ to any
static host. Generated output includes a GitHub Pages CNAME file for
mockery.montferret.dev.
The default build targets the domain root:
npm run buildTo build for a project subpath such as https://www.montferret.dev/mockery/:
MOCKERY_BASE_PATH=/mockery/ npm run buildOptional build settings:
MOCKERY_BASE_PATHdefaults to/MOCKERY_SITE_URLdefaults tohttps://mockery.montferret.devMOCKERY_OUT_DIRdefaults todist
npm run validateValidation builds both the root site and a /mockery/ subpath variant, then
checks required pages, product detail pages, paginated category pages, static
API files, internal links, product selectors, scenario entries, generated SVG
escaping, and accidental external dependencies.
Example scripts are in examples/ferret/ and the e-commerce scenario examples
are grouped under examples/ferret/ecommerce/. Dynamic product examples are
grouped under examples/ferret/dynamic-products/. The e-commerce catalog
contains 300 deterministic products, with 30 products in each category and
static pagination for both product listings and category pages. Examples use a
configurable base URL:
LET baseUrl = @baseUrl
LET doc = DOCUMENT(baseUrl + "/scenarios/ecommerce/products/")
npm run build
lab run examples/ferret/ecommerce-products.fql \
--serve ./dist@app \
--param baseUrl=@lab.static.appFor the focused e-commerce examples:
lab run examples/ferret/ecommerce/products.fql \
--serve ./dist@app \
--param baseUrl=@lab.static.app
lab run examples/ferret/ecommerce/search.fql \
--serve ./dist@app \
--param baseUrl=@lab.static.app
lab run examples/ferret/dynamic-products/basic.fql \
--serve ./dist@app \
--param baseUrl=@lab.static.app
lab run examples/ferret/dynamic-products/infinite-scroll.fql \
--serve ./dist@app \
--param baseUrl=@lab.static.appYou can also point baseUrl to any ordinary static server URL, for example
the local URL printed by npm run dev or npm run preview.
The build generates deterministic static JSON under dist/api, including:
api/products/index.jsonapi/products/page-1.jsonthroughapi/products/page-13.jsonapi/categories/index.jsonapi/reviews/index.jsonapi/reviews/<product-id>.jsonapi/search/products.jsonapi/dynamic-products/page-1.jsonthroughapi/dynamic-products/page-3.jsonapi/dynamic-products/featured.jsonapi/dynamic-products/search.jsonapi/dynamic-products/empty.jsonapi/dynamic-products/error.jsonapi/dynamic-products/slow-page-1.jsonapi/dynamic-products/slow-page-2.jsonapi/network/*.json
No backend runtime, database, analytics, external assets, or external SaaS services are required.