# Automatically grading CSS

While in principle, it is possible to use [Selenium](https://app.gitbook.com/o/-MKoTuXczViPzaai1tw3/s/-MKAQsDlg_P20iQy3JDs/~/changes/190/faq/automatic-grading-questions/autotest-v2/web-development-assignments-selenium-tests) to test the `css` properties defined for `html` elements, we advise against doing so in CodeGrade. The reason is that we run Selenium tests by using a web browser in headless mode, which can result in `css` rules working differently than they would while running your web browser with a normal display.\
\
Alternatively, we can use [Semgrep](https://semgrep.dev/) to test the structure of the `css` rules defined by the student.

## Design Semgrep patterns for testing CSS rules

Semgrep is used to perform code analysis by writing syntax rules in a human-readable format. Rules are made by generic or language-specific patterns, which are then searched for in the student's code. In Semgrep's [pattern syntax](https://semgrep.dev/docs/writing-rules/pattern-syntax/), you have:

* **Equivalences**: Matching code that *means the same thing* even though it looks different;
* **Wildcards / ellipsis (...)**: Matching any statement, expression or variable;
* **Metavariables ($X)**: Matching unknown expressions that you do not yet know what they will exactly look like, but want to be the same variable in multiple parts of your pattern;
* **Logical operators:** it is possible to logically combine simpler patterns to create more complex aggregate patterns.&#x20;

Let's inspect an example of a **Semgrep** pattern that checks the properties of a `btn` `css` class:

<pre data-line-numbers><code>patterns:
<strong>      - pattern-inside: |
</strong><strong>         .btn { ... }
</strong>      - pattern: |
<strong>         ...
</strong><strong>         margin: 20px;
</strong><strong>         ...
</strong><strong>      - pattern: |
</strong><strong>          ...
</strong><strong>          width: $ANYVALUE;
</strong><strong>          ...
</strong></code></pre>

* Line 1: with `patterns` we indicate that our overall pattern is composed of multiple sub-patterns;
* Lines 2 to 3: we require that the patterns that will be defined later have to be found within the body of a class named `btn`;
* Lines 4 to 7: we require that our pattern contains a margin setting of exactly 20 pixels;
* Lines 8 to 11: we require that our pattern contains a width setting with any possible value (notice the use of a metavariable)

{% hint style="info" %}
We suggest using the online [Semgrep editor](https://semgrep.dev/playground/new) to quickly develop new rules for testing `css` rules.
{% endhint %}

## Instructions

<figure><img src="/files/m737fTbmxH3WYp5SuXcs" alt=""><figcaption><p>A Semgrep test for Css rules. The test configuration is hidden to the students and the test is connected to a rubric category.</p></figcaption></figure>

1. In the **Setup** section of your AutoTest, drag and drop a **Script Block** into your configuration and type the following bash commands:

   ```bash
   python -mvenv ~/.venv/semgrep_1.43.0
   source ~/.venv/semgrep_1.43.0/bin/activate
   python -m pip install semgrep==1.43.0
   ```
2. In the Tests section of your AutoTest, drag and drop a **Code Structure Test** block. Specify the name of the CSS file you want to test in the "Student file" field.
3. Drag and drop a **Positive Match** block into your configuration and nest it within the Code Structure Test block. Copy and paste your Semgrep rule in the provided editor.
4. Build and Publish your snapshot.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.codegrade.com/automatic-grading-guides/web-development/automatically-grading-css.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
