{"id":15791256,"url":"https://github.com/levonet/todomvc-gemini","last_synced_at":"2026-03-07T22:31:11.213Z","repository":{"id":67322436,"uuid":"98538569","full_name":"levonet/todomvc-gemini","owner":"levonet","description":"Внедряем gemini в пример https://github.com/tastejs/todomvc","archived":false,"fork":false,"pushed_at":"2017-09-13T20:22:25.000Z","size":166,"stargazers_count":4,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"demo","last_synced_at":"2025-08-02T01:42:49.892Z","etag":null,"topics":["gemini","tutorial"],"latest_commit_sha":null,"homepage":"https://youtu.be/MKrX3Fld-WI?t=19797","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/levonet.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"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":"2017-07-27T13:23:08.000Z","updated_at":"2025-07-21T20:00:30.000Z","dependencies_parsed_at":"2023-03-17T14:45:58.549Z","dependency_job_id":null,"html_url":"https://github.com/levonet/todomvc-gemini","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/levonet/todomvc-gemini","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/levonet%2Ftodomvc-gemini","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/levonet%2Ftodomvc-gemini/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/levonet%2Ftodomvc-gemini/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/levonet%2Ftodomvc-gemini/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/levonet","download_url":"https://codeload.github.com/levonet/todomvc-gemini/tar.gz/refs/heads/demo","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/levonet%2Ftodomvc-gemini/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30234478,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T19:01:10.287Z","status":"ssl_error","status_checked_at":"2026-03-07T18:59:58.103Z","response_time":53,"last_error":"SSL_read: 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":["gemini","tutorial"],"created_at":"2024-10-04T23:00:36.589Z","updated_at":"2026-03-07T22:31:11.175Z","avatar_url":"https://github.com/levonet.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Пример внедрения gemini в [TodoMVC](https://github.com/tastejs/todomvc)\n\nТестирование вёрстки gemini-тестами позволяет быть уверенными, что внесение изменений в код проекта не сломает вёрстку в любой части этого проекта. Тестирование происходит сравнением снятого скриншота тестируемого элемента из текущей ревизии с эталонным скриншотом этого элемента.\n\nНиже приведено описания к соответствующим шагам (веткам `stepX`) внедрения gemini.\n\n## Локальный запуск тестов\n\n1. Первый тест — проверка работоспособности окружения тестирования\n   - Устанавливаем и запускаем [Selenium](http://docs.seleniumhq.org/download/).\n     ```sh\n     npm install -g selenium-standalone\n     selenium-standalone install\n     ```\n     В отдельном терминале запускаем Selenium-сервер, он понадобится на этапе локального запуска тестов.\n     ```sh\n     selenium-standalone start\n     ```\n   - Устанавливаем [gemini](https://github.com/gemini-testing/gemini) в проект.\n     ```sh\n     npm install --save-dev gemini\n     ```\n   - Устанавливаем и запускаем http-сервер, он понадобится только на этом шаге для открытия страницы.\n     ```sh\n     npm install http-server\n     ```\n     В отдельном терминале запускаем http-server.\n     ```sh\n     http-server\n     ```\n     Тестируемая страница доступна по адресу [http://127.0.0.1:8080/](http://127.0.0.1:8080/).\n   - Запуск gemini в режиме сохранения эталонных изображений.\n     ```sh\n     gemini update test/gemini/suites/todomvc.gemini.js\n     ```\n   - Запуск gemini в режиме тестирования.\n     ```sh\n     gemini test test/gemini/suites/todomvc.gemini.js\n     ```\n2. HTML-отчет для просмотра результатов о прохождении тестов\n   - Необходимо установить плагин [html-reporter](https://github.com/gemini-testing/html-reporter)\n     ```sh\n     npm install --save-dev html-reporter\n     ```\n     и подключить его в секции `system / plugins` в конфигурации gemini.\n   - Но есть и другие виды отчетов, которые устанавливаются как плагины:\n     - [stat-reporter](https://github.com/gemini-testing/stat-reporter) — отчет с агрегированной статистикой по браузерам\n     - [json-reporter](https://github.com/gemini-testing/json-reporter) — JSON-отчет для интеграции в пользовательские среды CI\n     - [gemini-teamcity](https://github.com/gemini-testing/gemini-teamcity) — отчет для интеграции с TeamCity\n3. Пишем модульные тесты на вёрстку для эффективного тестирования\n   - _«Каждый тестируемый объект разбивается на минимальные элементы, которые могут принимать различные визуальные состояния в зависимости от производимых над ними действий.»_\n4. Статические данные для тестируемой страницы\n   - Ограничения тестирования на живом API сервиса:\n     - внешний вид тестируемой HTML-страницы зависит от данных\n     - каждый `suit()` может выполняться параллельно в отдельном окне браузера, тесты могут изменять данные в произвольном порядке\n     - обнуление данных перед или после теста делает невозможным использование параллельности выполнения тестов\n   - Подмена API сервиса статическими данными:\n     - устанавливаем [json-server](https://github.com/typicode/json-server/)\n       ```sh\n       npm install json-server\n       ```\n     - запускаем http-сервер с подменой API сервиса `/api/todos`\n       ```sh\n       json-server db.json --port 8080 --routes routes.json --static . --read-only\n       ```\n5. Ограничения локального запуска\n   - Зависимость тестов от внешнего окружения — любое пользовательское действие может сломать прохождение тестов. Это частично можно решить за счет [retry](https://github.com/gemini-testing/gemini/blob/master/doc/config.md#browsers-settings).\n   - Тяжело поддерживать одинаковое окружение для разных разработчиков (ОС, версии браузеров, размер экрана).\n   - Нет возможности параллельного запуска тестов в браузерах на различных платформах (Windows, Linux, MAC).\n   - Неудовлетворительная скорость при большом количестве тестов — ресурсы локальной машины ограничены.\n   - Сложно автоматизировать запуск браузеров на той же машине, где запускаются тесты.\n\n## Запуск тестов в Selenium облаке\n\n0. Подключение к Selenium Grid\n   - Схема запуска тестов с Seleium Grid\n     - В идеальном мире браузер в Seleium Grid может открыть страницу с http-сервера, запущенного на машине разработчика.\n       ![Perfect World](scheme-perfectworld.png)\n     - Но в реальном мире машина разработчика находится за Firewall или NAT.\n       ![Real World](scheme-realworld.png)\n     - В таком случае поможет сервер со статическим адресом и [беспарольным доступом](http://www.thegeekstuff.com/2008/11/3-steps-to-perform-ssh-login-without-password-using-ssh-keygen-ssh-copy-id/) по ssh.\n       ![Tunneler](scheme-tunneler.png)\n       1. Поднимается тоннель между машиной разработчика и сервером, через тоннель пробрасывается порт http-сервера с машины разработчика на свободный порт сервера.\n       1. Браузеру передается хост и порт сервера в качестве хоста тестируемой страницы.\n   - Если вы используете собственный Seleium Grid, то для организации описанной выше схемы можно использовать gemini-плагин [ssh-tunneler](https://github.com/gemini-testing/ssh-tunneler).\n6. Запуск тестов в [SauceLabs](https://saucelabs.com)\n   - Для организации тоннеля с SauceLabs, необходимо установить [Sauce Connect Proxy](https://wiki.saucelabs.com/display/DOCS/Sauce+Connect+Proxy).\n   - Запускаем Sauce Connect Proxy, параметры авторизации передаем через переменные среды окружения.\n     ```sh\n     export SAUCE_USERNAME=xxxxxx\n     export SAUCE_ACCESS_KEY=yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy\n     path/to/sc\n     ```\n   - Подобрать `desiredCapabilities` необходимых браузеров можно с помощью [Platform Configurator](https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/).\n   - Gemini-плагин [gemini-saucelabs-info](https://github.com/gemini-testing/gemini-saucelabs-info) поможет авторизоваться в SauceLabs без передачи дополнительных параметров (перед запуском тестов убедитесь, что в данном терминале установлены параметры авторизации в переменных среды окружения).\n     ```sh\n     npm install --save-dev gemini-saucelabs-info\n     ```\n   - Тесты запускаются той-же командой, но с подменой `gridUrl` через переменную среды окружения.\n     Запуск gemini в режиме обновления скриншотов:\n     ```sh\n     gemini_grid_url=\"http://ondemand.saucelabs.com/wd/hub\" gemini update -b desktop-firefox test/gemini/suites/todomvc.gemini.js\n     ```\n     И запуска тестов в SauceLabs:\n     ```sh\n     gemini_grid_url=\"http://ondemand.saucelabs.com/wd/hub\" gemini test -b desktop-firefox test/gemini/suites/todomvc.gemini.js\n     ```\n\n## Автоматизация\n\n7. Сокращенные команды\n   - Секция конфигурации [sets](https://github.com/gemini-testing/gemini/blob/master/doc/config.md#sets) позволяет настроить различные варианты запуска тестов.\n   - Разделим конфигурацию для запуска тестов в локальном Selenium и в SauceLabs:\n     - запуск тестов локально\n       ```sh\n       gemini test -s local\n       ```\n     - запуска тестов в SauceLabs\n       ```sh\n       gemini_grid_url=\"http://ondemand.saucelabs.com/wd/hub\" gemini test -s sauce\n       ```\n   - Команды запуска тестов переносим в npm run-скрипт\n     ```sh\n     npm run gemini-local\n     npm run gemini-local-update\n     npm run gemini-sauce\n     npm run gemini-sauce-update\n     ```\n8. Автоматический запуск web-сервера из gemini\n   - Gemini расширяется [плагинами](https://github.com/gemini-testing/gemini/blob/master/doc/plugins.md), в которых можно задать пользовательские команды, подписанные на [события gemini](https://github.com/gemini-testing/gemini/blob/master/doc/programmatic-api.md#events).\n   - Пример плагина [gemini-json-server](https://github.com/levonet/gemini-json-server) для автоматического запуска web-сервера со стабом API. Устанавливаем и подключаем в конфигурации:\n     ```sh\n     npm install --save-dev git+https://github.com/levonet/gemini-json-server.git\n     ```\n   - Другие плагины, запускающие web-сервера во время запуска тестов:\n     - [gemini-ecstatic](https://github.com/w0rm/gemini-ecstatic) — сервер статики\n     - [gemini-express](https://github.com/Saulis/gemini-express) — запуск express\n     - [gemini-react](https://github.com/researchgate/gemini-react) — плагин для тестирования react компонент\n9. Оптимизация и хранение изображений\n   - Плагин оптимизации изображений [gemini-optipng](https://github.com/gemini-testing/gemini-optipng).\n     ```sh\n     npm install --save-dev gemini-optipng\n     ```\n     С уровнем сжатия `level: 5` уменьшает размер изображений до 50% за приемлемое время.\n   - Git Large File Storage — этот шаг рекомендуется, если необходимо хранить очень большое количество скриншотов в репозитории.\n     1. Устанавливаем [git-lfs](https://git-lfs.github.com) согласно инструкций.\n     2. Инициализируем маску пути, по которой будем хранить изображения\n        ```sh\n        git lfs track test/gemini/references/**/*.png\n        ```\n     3. Коммитим изображения.\n10. Запуск gemini в [Travis CI](travis-ci.com)\n   - Запуск тестов в браузерах — дорогая операция, по этому будем их запускать только для Pull Requests.\n   - SauceLabs ограничивает нас одним запуском тоннеля на одного пользователя, по этому устанавливаем [лимит на количество параллельных сборок](https://docs.travis-ci.com/user/customizing-the-build/#Limiting-Concurrent-Builds) в `1`.\n     ![Travis Settings](travis-settings.png)\n   - Публикация gemini html-отчета в Pull Request:\n     - для публикации отчетов воспользуемся [surge.sh](https://surge.sh)\n     - для публикации комментария со ссылками на отчеты понадобится [github token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/) на репозиторий\n   - Все необходимые ключи и токены для авторизации добавляем в переменные среды окружения Travis CI.\n     ![Travis Environment Variables](travis-env.png)\n\n## Оптимизация и сахар\n\n11. Настройка параллельности\n  - По браузерам — работает по умолчанию.\n  - По сессиям — устанавливается опцией `sessionsPerBrowser`. Её можно задать для каждого браузера в отдельности.\n  - Ограничение на общее одновременно открытие сессий устанавливается опцией `parallelLimit`. Это необходимо для работы с облачными сервисами предоставляющими доступ к браузерам.\n  - Ограничение на количество запущенных тестов для одной сессии устанавливается опцией `suitesPerSession`. При превышении этого ограничения старая сессия закрывается и открывается новая. Это ограничение можно задавать для каждого браузера в отдельности.\n12. Отчет о покрытии CSS тестами\n   - Gemini умеет строит отчет о покрытии CSS тестами, для этого нужно подключить утилиту для генерации HTML-отчета [gemini-coverage](https://github.com/gemini-testing/gemini-coverage).\n     ```sh\n     npm install --save-dev gemini-coverage\n     ```\n     Coverage настраивается в секции `system` конфигурации gemini.\n13. GUI для запуска тестов и сохранения эталонов\n   - [gemini-gui](https://github.com/gemini-testing/gemini-gui) можно установить глобально.\n     ```sh\n     npm install -g gemini-gui\n     ```\n   - Запускается gemini-gui в рабочей копии проекта, при необходимости можно использовать те же аргументы что и для `gemini`, но без команд `test` и `update`.\n     ```sh\n     gemini-gui\n     ```\n\n# AngularJS TodoMVC Example\n\n\u003e HTML is great for declaring static documents, but it falters when we try to use it for declaring dynamic views in web-applications. AngularJS lets you extend HTML vocabulary for your application. The resulting environment is extraordinarily expressive, readable, and quick to develop.\n\n\u003e _[AngularJS - angularjs.org](http://angularjs.org)_\n\n\n## Learning AngularJS\nThe [AngularJS website](http://angularjs.org) is a great resource for getting started.\n\nHere are some links you may find helpful:\n\n* [Tutorial](http://docs.angularjs.org/tutorial)\n* [API Reference](http://docs.angularjs.org/api)\n* [Developer Guide](http://docs.angularjs.org/guide)\n* [Applications built with AngularJS](https://www.madewithangular.com/)\n* [Blog](http://blog.angularjs.org)\n* [FAQ](http://docs.angularjs.org/misc/faq)\n* [AngularJS Meetups](http://www.youtube.com/angularjs)\n\nArticles and guides from the community:\n\n* [Code School AngularJS course](https://www.codeschool.com/courses/shaping-up-with-angular-js)\n* [5 Awesome AngularJS Features](http://net.tutsplus.com/tutorials/javascript-ajax/5-awesome-angularjs-features)\n* [Using Yeoman with AngularJS](http://briantford.com/blog/angular-yeoman.html)\n* [me\u0026ngular - an introduction to MVW](http://stephenplusplus.github.io/meangular)\n\nGet help from other AngularJS users:\n\n* [Walkthroughs and Tutorials on YouTube](http://www.youtube.com/playlist?list=PL1w1q3fL4pmgqpzb-XhG7Clgi67d_OHXz)\n* [Google Groups mailing list](https://groups.google.com/forum/?fromgroups#!forum/angular)\n* [angularjs on Stack Overflow](http://stackoverflow.com/questions/tagged/angularjs)\n* [AngularJS on Twitter](https://twitter.com/angularjs)\n* [AngularjS on Google +](https://plus.google.com/+AngularJS/posts)\n\n_If you have other helpful links to share, or find any of the links above no longer work, please [let us know](https://github.com/tastejs/todomvc/issues)._\n\n## Testsuite\n\nThe app uses [Karma](http://karma-runner.github.io/0.12/index.html) to run the tests located in the `test/` folder. To run the tests:\n\n```\n$ npm install\n$ npm test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flevonet%2Ftodomvc-gemini","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flevonet%2Ftodomvc-gemini","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flevonet%2Ftodomvc-gemini/lists"}