{"id":20035821,"url":"https://github.com/sw-tester/kanstructor","last_synced_at":"2026-03-09T01:31:57.761Z","repository":{"id":220052860,"uuid":"739815545","full_name":"sw-tester/kanstructor","owner":"sw-tester","description":"Write, test and repeat using YAML syntax","archived":false,"fork":false,"pushed_at":"2024-04-07T23:57:54.000Z","size":16355,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-03T08:54:32.610Z","etag":null,"topics":["opencv","playwright","qa-automation","qa-testing","typescript","yaml"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sw-tester.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-06T16:23:10.000Z","updated_at":"2024-04-08T00:24:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"e2113607-1b59-4361-8462-7ca0add5b8fa","html_url":"https://github.com/sw-tester/kanstructor","commit_stats":null,"previous_names":["5v1988/dancing-yaml","5v1988/kanstructor","sw-tester/kanstructor"],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/sw-tester/kanstructor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sw-tester%2Fkanstructor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sw-tester%2Fkanstructor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sw-tester%2Fkanstructor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sw-tester%2Fkanstructor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sw-tester","download_url":"https://codeload.github.com/sw-tester/kanstructor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sw-tester%2Fkanstructor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30279777,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T20:45:49.896Z","status":"ssl_error","status_checked_at":"2026-03-08T20:45:49.525Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["opencv","playwright","qa-automation","qa-testing","typescript","yaml"],"created_at":"2024-11-13T10:09:22.850Z","updated_at":"2026-03-09T01:31:57.721Z","avatar_url":"https://github.com/sw-tester.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n\t\u003cbr\u003e\n\t\u003cimg width=\"480\" src=\"src/assets/title-image.png\" alt=\"Kanstructor\"\u003e\n\t\u003cbr\u003e\n\t\u003cbr\u003e\n\u003c/h1\u003e\n\n\u003e Write, test and repeat using [YAML](https://spacelift.io/blog/yaml) language\n\n## Highlights\n\n- Write automated tests in plain Yaml\n- Design visual tests in a matter of minutes\n- Use OpenCV and/or Bitmap comparison to perform visual tests\n- Scale up browser compatibility checks\n- Of course, hassle-free installation\n\n## Installation\n\n**IMPORTANT:** Given this package is a node project, let's ensure to install `node` and `npm` as pre-requisites before setting up the project. [For further info.](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)\n\n```sh\nnpx setup-kanstructor demo-project\n```\n\nRunning the above command automatically sets up project structure, along with example files. [This section](#quick-start) provides the details on how the project resources are organised. Note that running this command also requires you to have `git` installed , if not install from [here](https://github.com/git-guides/install-git).\n\nIn order to run the tests, the following command does the job:\n\n```sh\ncd demo-project\nnpm run test\n```\nhttps://github.com/5v1988/kanstructor/assets/123231872/c6c01377-80ed-49eb-bd9c-59e5156a4c48\n\n## Quick Start\n\n- **Step 1** : The `src` folder under the project is going to be a root directory for all testing stuff, and the most of the project contents will be inside `resources` directory.\n\n- **Step 2** : Under `resources` folder, let's create `tests` folder which will contain test files in a plain YAML format. Note that, this package `kanstructor` identifies a file as a test file only if it ends in `*test.yaml`. [More on how to write tests?](#write-tests)\n\n- **Step 3** : Many a times, `CSS` and `XPath` values used to identify html elements will be used in several places across test files. To keep all such values in centralized place, the folder `elements` needs to be created within `resources`. Just like test files, the element files need to be ending in `*element.yaml` The following snippet shows some example element yaml.\n\n\t```yaml\n\t### Login page elements' xpath and css\n\n\tlogin_email: \"[name='email']\"\n\tlogin_password: \"[name='password']\"\n\tlogin_button: \"//button[normalize-space()='Login']\"\n\thome_logo: \"a[href*='home']\"\n\t```\n\n- **Step 4** : The next step is, the folders `extracted-contents` and `snapshots` need to be created to save all contents extracted during testing to external files and to keep baseline screenshots that will be verified against app under tests during testing respectively.\n\n- **Step 5** : All common configurations such as browser, env etc will have to be in the file: `config.yaml` under `config` folder. The following snippet shows some examples.\n\n  ```yaml\n    browser: chrome\n    headless: false\n    device: Desktop Chrome\n    url: https://github.com/5v1988/kanstructor\n  ```\n  In addition, there is also a way to configure options required to perform visual comparison of snapshots through the file `visual.tests.config.yaml` under `config` folder, and the following snippet shows the basic configurations that are generally used. \n\n  ```yaml  \n  output:\n    errorColor:\n      red: 255\n      green: 0\n      blue: 0\n    errorType: flat #\"flat\" or \"movement\" or \"flatDifferenceIntensity\" or \"movementDifferenceIntensity\" or \"diffOnly\"\n    transparency: 0.3\n    largeImageThreshold: 1200\n    useCrossOrigin: false\n    boundingBoxes:\n      - left: 0\n        top: 0\n        right: 1300\n        bottom: 800\n  returnEarlyThreshold: 0\n  scaleToSameSize: false\n  ignore: antialiasing # \"nothing\" or \"less\" or \"antialiasing\" or \"colors\" or \"alpha\";\n  ```\n- **Step 6** : Lastly, to run all tests, the test runner `runMe.js` needs to be created in the project as follows:\n\n  ```js\n    import runMe from 'kanstructor'\n    runMe();\n  ```\nNow execute tests using `node src/runMe.js` ( or `npm run test`) from command line. Note that, not necessarily that the runner method must always be named as `runMe`; Once all setup is complete, the below is the expected project structure\n\n\n```sh\n.\n├── README.md\n├── node_modules\n├── package-lock.json\n├── package.json\n└── src\n    ├── resources\n    │   ├── config\n    │   │   └── config.yaml\n    |   │   └── visual.tests.config.yaml\n    │   ├── elements\n    │   │   └── todo-element.yaml\n    │   ├── reports\n    │   │   ├── results.html\n    │   │   └── results.json\n    │   ├── snapshots\n    │   │   ├── original-screenshot-1.png\n    │   │   └── reference-screenshot-1.png\n    │   └── tests\n    │       └── todo-test.yaml\n    └── runMe.js\n\n```\n\n## Write Tests\n\n — Tests are expected to be written in Yaml files, otherwise known as test files while using this package. Each of these tests should have to be written using 3 A's of testing: `Arrange-Act-Assert`\n\n ```yaml\n\ndescription: Some tests on cypress todo demo site\ntests:\n  - name: Set and delete todo lists\n    exclude: false\n\n    arrange:\n      - name: Open the url for the app under test\n        action: openUrl\n        url: url\n\n      - name: Set value for the first item in storage\n        action: setValue\n        key: firstItem\n        value: Schedule doctor appointment\n\n      - name: Set value for the second item in storage\n        action: setValue\n        key: secondItem\n        value: Prepare a blog content\n\n    act:\n      - name: Add the first item\n        id: 10001\n        role: textbox\n        text: What needs to be done?\n        action: type\n        value: ${firstItem}\n\n      - name: Press Enter\n        pause: 1\n        action: press\n        value: Enter\n\n      - name: Add the second item\n        locator: .new-todo\n        action: type\n        value: ${secondItem}\n\n      - name: Press Enter\n        pause: 1\n        action: press\n        value: Enter\n\n      - name: Add the third item\n        refId: 10001\n        value: Fix the air conditioner\n\n      - name: Press Enter\n        pause: 1\n        action: press\n        value: Enter\n\n      - name: Screenshot after adding all items\n        pause: 1\n        action: snapshot\n        path: \"src/example/resources/snapshots/original-screenshot-1.png\"    \n\n      - name: Hover to the first item\n        text: ${firstItem}\n        action: hover\n\n      - name: Delete the first item\n        pause: 2\n        locator: \"//div[normalize-space()='Schedule doctor appointment']//button\"\n        action: click\n\n      - name: Hover to the second item\n        text: ${secondItem}\n        action: hover\n\n      - name: Delete the second item\n        pause: 2\n        locator: \"//div[normalize-space()='Prepare a blog content']//button\"\n        action: click\n\n      - name: Hover to the third item\n        text: Fix the air conditioner\n        action: hover\n\n      - name: Delete the third item\n        pause: 2\n        locator: \"//div[normalize-space()='Fix the air conditioner']//button\"\n        action: click\n\n      - name: Screenshot after deleting all items\n        pause: 1\n        action: snapshot\n        path: \"src/example/resources/snapshots/original-screenshot-2.png\"\n\n    assert:\n      - name: Verify if the first item deleted\n        pause: 2\n        type: standard\n        text: ${firstItem} \n        state: invisible\n\n      - name: Verify if the second item deleted\n        pause: 2\n        type: standard\n        text: ${secondItem}\n        state: invisible\n\n      - name: Verify if the third item deleted\n        pause: 2\n        type: standard\n        text: Fix the air conditioner\n        state: invisible\n\n      - name: Compare screenshot after all items added\n        type: snapshot\n        original: \"src/example/resources/snapshots/original-screenshot-1.png\"\n        reference: \"src/example/resources/snapshots/reference-screenshot-1.png\"\n        tolerance: 1\n\n  # Visual comparison using OpenCV\n      - name: Compare screenshot after all items deleted by OpenCV\n        type: glancing\n        original: \"src/example/resources/snapshots/original-screenshot-2.png\"\n        reference: \"src/example/resources/snapshots/reference-screenshot-2.png\"\n        tolerance: 3\n\n ```\n ### Guidelines\n\n — A test file can have more than one test, however, our recommendation is to have a few of them, organized by some commonalities\n\n — A test folder `tests` can contain several test files; No limits\n\n — The high-level blocks — Arrange, Act and Assert, contain a sequence of steps to perform certain actions during testing.\n\n### Locating Strategy\n  This package allows to locate page elements using their accessible name and implicit role. For instance, in the below example, the textbox is located using its placeholder text `What needs to be done?`.\n  ```yaml\n  - name: Add the first item\n    id: 10001\n    role: textbox\n    text: What needs to be done?\n    action: type\n    value: ${firstItem}\n  ```\n  It's also important to that `role` must always go with `text`, and at the moment, the other supported roles are as follows:\n  - textbox\n  - checkbox\n  - radio\n  - link\n  - option\n  - button\n  - slider\n  - switch\n\n  Alternatively, If you are well versed in writing `Xpath` or `CSS`, you can simply use `locator` attribute in the blocks.\n\n### Reusing Blocks\n  By setting `id` for a test block, it will become reusable and can be used again within the same test or even in the test under the different yaml file. This is done using `refId` when needed.\n  ```yaml\n  - name: Add the first item\n    id: 10001\n    role: textbox\n    text: What needs to be done?\n    action: type\n    value: ${firstItem}\n  ```\n  In the above example, the `id` is set as `10001`. So, by using this id as `refId`, this test block can be re-used as follows:\n\n  ```yaml\n  - name: Add the third item\n    refId: 10001\n    value: Fix the air conditioner\n  ```\n  While doing so, all attributes except `name` and `value` will be taken up from the original test block. \n\n### State management\n  Sometimes, the test data either static or dynamic will have to be shared among blocks. This can be achieved by setting such values with an action named `setValue` so they can be accessed later part of the tests using `${variableName}` or `$variableName`. \n\n```yaml   \n- name: Set value for the first item in storage\n  action: setValue\n  key: firstItem\n  value: Schedule doctor appointment\n```\n\nAs you can see from this example, the value for the key `firstItem` is set-up once and it can be accessed anywhere else later with `text`(or `value`) later as shown below.\n\n```yaml\n- name: Verify if the first item deleted\n  pause: 2\n  type: standard\n  text: ${firstItem} \n  state: invisible\n```\n\n## Block Reference\n\n### Arrange\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eAction\u003c/th\u003e\n    \u003cth\u003eDescription\u003c/th\u003e\n    \u003cth\u003eKeys\u003c/th\u003e\n    \u003cth\u003eExample\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cpre\u003eopenUrl\u003c/pre\u003e\u003c/td\u003e\n    \u003ctd\u003eOpen an app url in browser\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      name,\u003cbr\u003e\n      url\u003cbr\u003e\n      Optional — \u003cbr\u003e\n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: openUrl \n          url: https://github.com/5v1988\n      \u003c/pre\u003e  \n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cpre\u003esetValue\u003c/pre\u003e\u003c/td\u003e\n    \u003ctd\u003eSet test data in value storage\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      key,\u003cbr\u003e\n      value\u003cbr\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: Set value for the username\n          action: setValue\n          key: firstItem\n          value: 5v1988\n      \u003c/pre\u003e  \n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n### Act\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eAction\u003c/th\u003e\n    \u003cth\u003eDescription\u003c/th\u003e\n    \u003cth\u003eKeys\u003c/th\u003e\n    \u003cth\u003eExample\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n      \u003cpre\u003etype\u003c/pre\u003e\n    \u003c/td\u003e\n    \u003ctd\u003eEnter characters into textboxes\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      name,\u003cbr\u003e\n      action,\u003cbr\u003e\n      locator,\u003cbr\u003e\n      value \u003cbr\u003e\n      Optional — \u003cbr\u003e\n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n          - name: Type in username\n            action: type\n            locator: \"input[name='email']\"\n            value: 5v1988@gmail.com\n        \u003c/pre\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n        check,\n        uncheck\n    \u003c/td\u003e\n    \u003ctd\u003eCheck (or Uncheck) radio button/checkbox\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      name,\u003cbr\u003e\n      action,\u003cbr\u003e\n      locator,\u003cbr\u003e\n      Optional — \u003cbr\u003e\n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: Choose a gender\n          action: check\n          locator: \"input[type='checkbox']\"\n      \u003cpre\u003e    \n    \u003c/td\u003e  \n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eclick, \u003cbr\u003e\n      doubleclick \u003cbr\u003e\n    \u003c/td\u003e\n    \u003ctd\u003eClick (or Doubleclick) button/link\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      name,\u003cbr\u003e\n      action,\u003cbr\u003e\n      locator,\u003cbr\u003e\n      Optional — \u003cbr\u003e\n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: Type in username\n          action: click\n          locator: '#file-submit'\n      \u003c/pre\u003e  \n    \u003c/td\u003e  \n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eselect\u003c/td\u003e\n    \u003ctd\u003eSelect a dropdown value\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      name,\u003cbr\u003e\n      action,\u003cbr\u003e\n      locator,\u003cbr\u003e\n      value \u003cbr\u003e\n      Optional — \u003cbr\u003e\n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: choose_dropdown\n          locator: \"#dropdown\"\n          action: select\n          value: Option 2\n      \u003c/pre\u003e\n    \u003c/td\u003e  \n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003epress\u003c/td\u003e\n    \u003ctd\u003eSimulate a key press\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      name,\u003cbr\u003e\n      action,\u003cbr\u003e\n      value \u003cbr\u003e\n      Optional — \u003cbr\u003e\n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: Press enter\n          action: press\n          value: Enter\n      \u003c/pre\u003e\n    \u003c/td\u003e  \n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eclear, \u003cbr\u003e\n        focus, \u003cbr\u003e\n        hover\u003cbr\u003e\n      \u003c/td\u003e\n    \u003ctd\u003eClear (or focus or hover) on html element\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      name,\u003cbr\u003e\n      action,\u003cbr\u003e\n      locator \u003cbr\u003e\n      Optional — \u003cbr\u003e\n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: hover on the login link\n          locator: \"//button[@id='login']\"\n          action: hover\n      \u003c/pre\u003e\n    \u003c/td\u003e  \n  \u003c/tr\u003e    \n  \u003ctr\u003e\n    \u003ctd\u003esnapshot\u003c/td\u003e\n    \u003ctd\u003eTake a screenshot of a current window\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      name,\u003cbr\u003e\n      action,\u003cbr\u003e\n      path \u003cbr\u003e\n      Optional — \u003cbr\u003e\n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: Screenshot the login failure\n          pause: 1\n          action: snapshot\n          path: \"path/to/save.png\"\n      \u003c/pre\u003e\n    \u003c/td\u003e  \n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003eupload\u003c/td\u003e\n    \u003ctd\u003eUpload a file to the app\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      name,\u003cbr\u003e\n      action,\u003cbr\u003e\n      locator \u003cbr\u003e\n      path \u003cbr\u003e     \n      Optional — \u003cbr\u003e\n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: Upload an image\n          action: upload\n          locator: '#file-upload'\n          path: src/example/innerText.txt\n      \u003c/pre\u003e\n    \u003c/td\u003e  \n  \u003c/tr\u003e  \n  \u003ctr\u003e\n    \u003ctd\u003eextract\u003c/td\u003e\n    \u003ctd\u003e\n      Extract text contents from the current window. \u003cbr\u003e\n      Page source of the current window will be extracted by default\u003cbr\u003e\n      and locator attribute is mandatory if `extractType` is given\n    \u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      name,\u003cbr\u003e\n      action,\u003cbr\u003e\n      path \u003cbr\u003e\n      Optional — \u003cbr\u003e\n      locator \u003cbr\u003e\n      extractType — textContents, innerText, innerHTML \u003cbr\u003e \n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: Extract form contents\n          action: extract\n          path: \"path/to/save.txt\"\n          locator: \"form#customer\"\n          extractType: innerText\n      \u003c/pre\u003e\n    \u003c/td\u003e  \n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003cpre\u003esetValue\u003c/pre\u003e\u003c/td\u003e\n    \u003ctd\u003eSet test data in value storage\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      key,\u003cbr\u003e\n      value( or locator)\u003cbr\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: Set value for the username\n          action: setValue\n          key: firstItem\n          value: 5v1988\n      \u003c/pre\u003e  \n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n### Assert\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eType\u003c/th\u003e\n    \u003cth\u003eDescription\u003c/th\u003e\n    \u003cth\u003eKeys\u003c/th\u003e\n    \u003cth\u003eExample\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003estandard\u003c/td\u003e\n    \u003ctd\u003eAssert the expectation by using page element(s)\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      name,\u003cbr\u003e\n      type,\u003cbr\u003e\n      locator, or (role or/and text)\u003cbr\u003e\n      role (always used with 'text'),\u003cbr\u003e\n      text,\u003cbr\u003e\n      state (accepted values: visible, invisible,\u003cbr\u003e\n      enabled, disabled, checked, unchecked, containText),\u003cbr\u003e\n      Optional — \u003cbr\u003e\n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: Verify dropdown selected\n          type: element\n          locator: \"//option[@selected]\"\n          state: containText\n          text: Option 2\n      \u003c/pre\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003ecompare\u003c/td\u003e\n    \u003ctd\u003eAssert if text matches with value storage\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      key,\u003cbr\u003e\n      locator (or value or text),\u003cbr\u003e\n      Optional — \u003cbr\u003e\n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: Compare username\n          key: ${username}\n          text: 5v1988\n      \u003c/pre\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003esnapshot\u003c/td\u003e\n    \u003ctd\u003eCompare the expected screenshot with the actual one on the current screen\u003c/td\u003e\n    \u003ctd\u003eRequired — \u003cbr\u003e\n      name,\u003cbr\u003e\n      type,\u003cbr\u003e\n      original,\u003cbr\u003e\n      reference,\u003cbr\u003e\n      tolerance (lies between 0 (to be exact) and 100 (ignore comparison))\u003cbr\u003e\n      Optional — \u003cbr\u003e\n      pause\n    \u003c/td\u003e\n    \u003ctd\u003e\n      \u003cpre lang=\"yaml\"\u003e\n        - name: Verify failure screen\n          type: snapshot\n          original: \"path/to/screenshot.png\"\n          reference: \"path/to/reference.png\"\n          tolerance: 1\n      \u003c/pre\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003ctable\u003e  \n\n\n## Roadmap\n\n— [X] Browser \u003cbr\u003e\n— [X] Summary report \u003cbr\u003e\n— [O] Parameterized tests \u003cbr\u003e\n— [O] Mobile \u003cbr\u003e\n\n## Contributing\n\nWe really appreciate and value the work that you do for this project. Needless to say, contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make will benefit everybody else and are greatly appreciated.\n\n\nPlease read [our contribution guidelines](CONTRIBUTING.md), and thank you for being involved!\n\n### Code of Conduct\n\nSee the [Code of Conduct](CODE-OF-CONDUCT.md) for details. Basically it comes down to:\n\u003e In the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, gender identity and expression, level of experience,\nnationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Support\n\nhttps://discord.gg/GWfMu5Cwq6\n\n## License\n\nThis project is licensed under the **GPLv3 license**.\n\nSee [LICENSE](LICENSE) for more information.\n\nHappy Testing!","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsw-tester%2Fkanstructor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsw-tester%2Fkanstructor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsw-tester%2Fkanstructor/lists"}