Initial commit: Supermarket scraper MVP
This commit is contained in:
173
.cursor/rules/requestly-test-rules.mdc
Normal file
173
.cursor/rules/requestly-test-rules.mdc
Normal file
@@ -0,0 +1,173 @@
|
||||
---
|
||||
globs: .requestly-supermarket/**/*.json
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
This rule provides instructions to generate API tests for Requestly requests:
|
||||
|
||||
- The Requestly HTTP requests are stored as JSON files in `.requestly-supermarket/` directory and subdirectories.
|
||||
- The `name` key shows the name of the request.
|
||||
- The `request.url` key shows the URL of the request.
|
||||
- The `request.body` key shows the body of the request. It is a string representation of a JSON body.
|
||||
- The `request.scripts.postResponse` key holds the API test. It is a string representation of a JavaScript code.
|
||||
|
||||
## Test Format
|
||||
|
||||
The test format is:
|
||||
|
||||
```js
|
||||
rq.test("Test name", () => {
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
## Requestly Specific Methods
|
||||
|
||||
The tests use Chai.js syntax with Requestly abstraction on top. Requestly provides a few methods on top of Chai.js.
|
||||
|
||||
### Assertion
|
||||
|
||||
Use `rq.expect` for assertions:
|
||||
|
||||
```js
|
||||
rq.expect(actualValue).to.equal(expectedValue);
|
||||
```
|
||||
|
||||
### Accessing Request and Response Objects
|
||||
|
||||
Use `rq.request` and `rq.response` to access the request and response objects. Use `rq.response.body` to access the response body. Convert it to JSON before working with it.
|
||||
|
||||
### Checking Statuses
|
||||
|
||||
Requestly provides custom status code names for some of the most common status codes. You can use these to check the response status:
|
||||
|
||||
```js
|
||||
// Success responses
|
||||
rq.response.to.be.ok // 2XX
|
||||
rq.response.to.be.success // 200
|
||||
rq.response.to.be.accepted // 202
|
||||
|
||||
// Client error responses
|
||||
rq.response.to.be.badRequest // 400
|
||||
rq.response.to.be.unauthorized // 401
|
||||
rq.response.to.be.forbidden // 403
|
||||
rq.response.to.be.notFound // 404
|
||||
rq.response.to.be.rateLimited // 429
|
||||
rq.response.to.be.clientError // 4XX
|
||||
|
||||
// Server error responses
|
||||
rq.response.to.be.serverError // 5XX
|
||||
|
||||
// Other status categories
|
||||
rq.response.to.be.error // 4XX or 5XX
|
||||
rq.response.to.be.info // 1XX
|
||||
rq.response.to.be.redirection // 3XX
|
||||
```
|
||||
|
||||
### Checking Response Body
|
||||
|
||||
Use `.to.have.body` to check the response body verbatim:
|
||||
|
||||
```js
|
||||
// Checks if response body exactly matches expected value.
|
||||
rq.response.to.have.body(expectedValue: string)
|
||||
```
|
||||
|
||||
Use `.to.have.jsonBody` to check for the existence of a particular JSON key and its value:
|
||||
|
||||
```js
|
||||
// Checks if a path exists in the response.
|
||||
rq.response.to.have.jsonBody(path: string)
|
||||
rq.response.to.have.jsonBody("user.name");
|
||||
|
||||
// Checks if a JSON path has a specific value.
|
||||
rq.response.to.have.jsonBody(path: string, value: any)
|
||||
rq.response.to.have.jsonBody("user.name", "John");
|
||||
```
|
||||
|
||||
Use `.to.have.jsonSchema` to validate against a JSON schema:
|
||||
|
||||
```js
|
||||
// Validates the response body against a JSON schema. Accepts optional Ajv configuration.
|
||||
rq.response.to.have.jsonSchema(schema: object, ajvOptions?: AjvOptions)
|
||||
|
||||
rq.response.to.have.jsonSchema({
|
||||
type: "object",
|
||||
required: ["id", "name"],
|
||||
properties: {
|
||||
id: { type: "number" },
|
||||
name: { type: "string" },
|
||||
email: { type: "string", format: "email" }
|
||||
}
|
||||
}, { allErrors: true });
|
||||
```
|
||||
|
||||
### Environment and Global Variables
|
||||
|
||||
Use `rq.environment.get("variable_name")` to get the value of an environment variable. Use `rq.globals.get("variable_name")` to get the value of a global variable. The `.requestly-supermarket/environments/global.json` has a list of all global variables. The other JSON files in the folder hold the different environments. Each key in the `variables` property is the name of the variable.
|
||||
|
||||
## Test Categories
|
||||
|
||||
The most common tests are:
|
||||
|
||||
- Response status check
|
||||
- Response body check
|
||||
- Data validation
|
||||
|
||||
## Common Test Patterns
|
||||
|
||||
### Response Status Check
|
||||
|
||||
```js
|
||||
rq.test("Request is successful", () => {
|
||||
rq.response.to.be.ok
|
||||
})
|
||||
```
|
||||
|
||||
### Response Body Check
|
||||
|
||||
```js
|
||||
// Check individual properties
|
||||
|
||||
rq.test("Response has property_name",()=>{
|
||||
var body = JSON.parse(rq.response.body)
|
||||
rq.expect(body).to.have.property("property_name").that.is.a("type")
|
||||
})
|
||||
|
||||
// Validate against JSON schema
|
||||
rq.test("Match JSON schema", () => {
|
||||
rq.response.to.have.jsonSchema({
|
||||
...
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### Data Validation
|
||||
|
||||
```js
|
||||
rq.test("Returns valid data", () => {
|
||||
rq.expect(body.property_name).to.equal("expected_value")
|
||||
})
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Group related tests together
|
||||
- Use descriptive test names
|
||||
- Test one concept per test
|
||||
- Include both positive and negative cases
|
||||
- First, check response status, then check the body, then check data validation
|
||||
- Test for required fields
|
||||
- Validate data types
|
||||
- Check array contents
|
||||
- Verify nested structures
|
||||
|
||||
## Specific to This Project
|
||||
|
||||
This project contains API requests for:
|
||||
- Magnit API endpoints (Russian supermarket chain)
|
||||
- The API uses POST requests with JSON bodies
|
||||
- Responses typically include arrays of items with fields like `id`, `name`, `price`, etc.
|
||||
- Prices are stored in kopecks (e.g., 24999 = 249.99 rubles)
|
||||
- Responses may include pagination information
|
||||
- Some endpoints require authentication via headers or cookies
|
||||
Reference in New Issue
Block a user