{"id":21759514,"url":"https://github.com/galenframework/galen-bootstrap","last_synced_at":"2025-08-19T09:10:35.819Z","repository":{"id":78350459,"uuid":"47646538","full_name":"galenframework/galen-bootstrap","owner":"galenframework","description":null,"archived":false,"fork":false,"pushed_at":"2017-03-28T14:17:30.000Z","size":26,"stargazers_count":16,"open_issues_count":1,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-08-08T12:37:26.592Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/galenframework.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":"2015-12-08T20:05:18.000Z","updated_at":"2021-01-20T20:39:42.000Z","dependencies_parsed_at":"2023-04-17T16:17:03.694Z","dependency_job_id":null,"html_url":"https://github.com/galenframework/galen-bootstrap","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/galenframework/galen-bootstrap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/galenframework%2Fgalen-bootstrap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/galenframework%2Fgalen-bootstrap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/galenframework%2Fgalen-bootstrap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/galenframework%2Fgalen-bootstrap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/galenframework","download_url":"https://codeload.github.com/galenframework/galen-bootstrap/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/galenframework%2Fgalen-bootstrap/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271128666,"owners_count":24703879,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-19T02:00:09.176Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2024-11-26T11:33:17.919Z","updated_at":"2025-08-19T09:10:35.798Z","avatar_url":"https://github.com/galenframework.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Galen Bootstrap\n==================\n\n\nGalen Bootstrap is a simple JavaScript layout testing framework based on Galen Framework. It makes it easier to get started with layout testing for responsive website and also provides functionality for the following types of testing:\n\n* Image Diff testing. Comparing images from previous iteration\n* Long words layout testing. Inserting long words in selected page elements and testing that the layout did not break. Usefull for websites that are supposed to be translated to different languages\n* Browser size variations testing with randomization support\n\n\nConfiguring\n---------------------\nDownload the [galen-bootstrap](https://github.com/galenframework/galen-bootstrap/tree/master/galen-bootstrap) directory and copy it to your test project. After this you can create an `init.js` script where you will load the `galen-bootstrap/galen-bootstrap.js` script and configure all devices and a website url for testing.\n\n```javascript\nload(\"galen-bootstrap/galen-bootstrap.js\");\n\n$galen.settings.website = \"http://testapp.galenframework.com\";\n$galen.registerDevice(\"mobile\", inLocalBrowser(\"mobile emulation\", \"450x800\", [\"mobile\"]));\n$galen.registerDevice(\"tablet\", inLocalBrowser(\"tablet emulation\", \"600x800\", [\"tablet\"]));\n$galen.registerDevice(\"desktop\", inLocalBrowser(\"desktop emulation\", \"1024x768\", [\"desktop\"]));\n```\n\nIn the example above we have declared a test website \"[http://testapp.galenframework.com](http://testapp.galenframework.com)\" and also registered 3 devices: `mobile`, `tablet`, `desktop`. All devices and settings are stored in `$galen` object.\n\n\nSimplest layout test\n---------------------\nJust create a homePage.test.js file and load your `init.js` script. In order to declare a test that will run on all devices you need to use `testOnAllDevices` function.\n\n```javascript\nload(\"init.js\");\n\ntestOnAllDevices(\"Welcome page test\", \"/\", function (driver, device) {\n    // Here the driver will be provided and you don't have to take care of it\n    // Also once the test finishes it will automatically quit the driver.\n\n    // Here we call standard checkLayout function from Galen Api (http://galenframework.com/docs/reference-galen-javascript-api/#checkLayout)\n    checkLayout(driver, \"homepage.gspec\", device.tags, device.excludedTags);\n});\n```\n\n`testOnAllDevices` function takes free parameters:\n1. testNamePrefix - a name that will be used in resulting reports\n2. Resource path. A starting page for test. \n3. test callback. A function that will be called when the test is executed. This callback should take 2 arguments: a webdriver and a device on which this test is executed\n\nThe above example will execute \"Welcome page test\" on all registered devices. Each devices has its own tags and you can pass these tags to `checkLayout` function from `device.tags`.\nBut if you want to run your test only on specific devices, then you have to use `testOnDevice` function and pass a device as a first argument to it:\n\n```javascript\ntestOnDevice($galen.devices.mobile, \"Welcome page test\", \"/\", function (driver, device) {\n    checkLayout(driver, \"homepage.gspec\", device.tags, device.excludedTags);\n});\n```\n\nIf you need to select an array of devices then the best way to do it is using `testOnDevices` function and pass an array of devices as a first argument:\n\n```javascript\ntestOnDevice([\n    $galen.devices.mobile,\n    $galen.devices.tablet\n    ], \"Welcome page test\", \"/\", function (driver, device) {\n    checkLayout(driver, \"homepage.gspec\", device.tags, device.excludedTags);\n});\n```\n\n\nBrowser sizes variations testing\n--------------------\nIt might be also handy to test your website on different sizes. for this case you can use `checkMultiSizeLayout` function.\n\n```javascript\ntestOnDevice($galen.devices.desktop, \"Welcome page test\", \"/\", function (driver, device) {\n    checkMultiSizeLayout({ \n        driver: driver,\n        spec: \"homepage.gspec\",\n        tags: device.tags,\n        excludedTags: device.excludedTags,\n        sizes: [\"900x768\", \"920x768\", \"940x768\", \"1024x768\"]\n    });\n});\n```\n\n`checkMultiSizeLayout` function takes a single argument which has the following fields:\n\n* *driver* - a WebDriver instance\n* *spec* - a path to spec file\n* *tags* - an array of tags\n* *excludedTags* - an array of tags that should be excluded\n* *sizes* - an array of sizes\n\nThe above example will run layout test 4 times and each time it will resize browser with the declared size from each iteration\n\nBut it might be easier to declare a range of sizes and use `sizeVariations` to generate an array of size from that range:\n\n```javascript\n$galen.registerDevice(\"desktop\", inSingleBrowser(\"desktop emulation\", \"1024x768\", [\"desktop\"]));\n$galen.devices.desktop.sizeRange = [\"900x600\", \"1200x768\"];\n\ntestOnAllDevices(\"Welcome page test\", \"/\", function (driver, device) {\n    checkMultiSizeLayout({ \n        driver: driver,\n        spec: \"homepage.gspec\",\n        tags: device.tags,\n        excludedTags: device.excludedTags,\n        sizes: sizeVariations(device.sizeRange, 8)\n    });\n});\n\n```\n`sizeVariations` function is used in order to generate an array of sizes between specified range. Takes two arguments:\n1. sizeRange - An array of 2 strings. e.g. [\"450x600\", \"600x600\"]\n2. iterationAmount - an amount of generated variations. If not defined then it will generate all possible variations based on width.\n\n\nRandom size testing\n--------------------\nNot always it is usefull to run all your tests on all possible browser sizes. It might just take too much time and resources. But if you still want to cover all of possible size but execute less tests you can use `sizeRandomVariations` function. It works the same way as `sizeVariations` but adds small randomization for each iteration.\n\n```javascript\n$galen.registerDevice(\"desktop\", inSingleBrowser(\"desktop emulation\", \"1024x768\", [\"desktop\"]));\n$galen.devices.desktop.sizeRange = [\"900x600\", \"1200x768\"];\n\ntestOnAllDevices(\"Welcome page test\", \"/\", function (driver, device) {\n    checkMultiSizeLayout({ \n        driver: driver,\n        spec: \"homepage.gspec\",\n        tags: device.tags,\n        excludedTags: device.excludedTags,\n        sizes: sizeRandomVariations(device.sizeRange, 6)\n    });\n});\n```\n\nIn the above example it will take delta = (1200 - 900) / 6 and will use this value to create a random size within this delta range. For instance in that particular example the delta will be 50 and we will get 6 iterations: 900 + random of 50, 950 + random of 50, 1000 + random of 50 etc. It could be something like: [912, 951, 1046, 1059, 1132, 1900]\n\n\n\nLong words testing\n----------------------\nWhen a website is supposed to be displayed in multiple countries with different languages it is an often problem that some long word in a specific element breaks the layout. It might not only be due to i18n support but this issue could happen due to user input. Fortunately this could be tested by replacing the elements with a long word (e.g. german \"Freundschaftsbezeigungen\") before checking layout. You don't have to rewrite your tests or spec for this type of testing. All you need to do is to mark the objects on your page for which it should replace a text with `long_word_test` group. This can be done using `@groups` section.\n\n\n```gspec\n@objects\n    header                   #header .middle-wrapper\n        logo                    #header-logo\n        text                    h1\n    menu                     #menu ul\n        item-*                  li a\n    content                  #content\n    footer                   #footer\n\n@groups\n    long_word_test                  header.text,menu.item-*\n```\n\nIn the example above we have marked a header text and all menu items as a group `long_word_test`. Now we need to check the layout using `checkLongWordsLayout` function.\n\n```javascript\ntestOnAllDevices(\"Long Words. Welcome page test with\", \"/\", function (driver, device) {\n    checkLongWordsLayout({\n        driver: driver, \n        spec: \"homepage.gspec\",\n        tags: device.tags,\n        excludedTags: device.excludedTags,\n    });\n});\n```\n\nAs you can see the function is very simmilar to standard `checkLayout` function from Galen API. By default it replaces text with `\"Freundschaftsbezeigungen\"` word but you can change this behaviour in settings:\n\n```javascript\n$galen.settings.longWordsTesting.replaceText = \"My_very_long_word\";\n```\n\n\nImage Diff Based Testing\n------------------------\nGalen is also capable of testing images of individual parts of the page using [image spec](http://galenframework.com/docs/reference-galen-spec-language-guide/#Image). But it takes a bit more effort in this case as you have to prepare the sample images with which Galen will compare the actual image on screenshot. Galen Bootstrap provides another interesting image validation implementation. You can use `checkImageDiff` function in order to compare individual elements with previous images from previous test run. How is this possible? It works like this:\n\n1. You need to mark the object with  `image_diff_validation` or `image_diff_validation_blur` groups. This way you can select which elements should be tested with this approach.\n2. The first run gives error as there are obviously no images from previous test run. This is just a dry run to generate image samples.\n3. In the end it creates a page dump and copies all images for all objects into specified storage.\n4. Next time you run your tests it takes image samples from last iteration and uses them in order to compare with the current images on screenshot.\n5. If something is different you will get an error in the report.\n\nHere is an example of how to mark elements in gspec file:\n\n```gspec\n@objects\n    header                   #header .middle-wrapper\n        logo                    #header-logo\n        text                    h1\n    menu                     #menu ul\n        item-*                  li a\n    content                  #content\n    footer                   #footer\n\n@groups\n    image_diff_validation           header.logo\n    image_diff_validation_blur      menu.item-*,header.text\n```\n\nAnd the test:\n\n```javascript\ntestOnAllDevices(\"Image Diff. Welcome page test\", \"/\", function (driver, device) {\n    checkImageDiff({\n        driver: driver, \n        storage: \"image-diff/welcome-page-\" + device.deviceName, \n        spec: \"homepage.gspec\"\n    });\n});\n```\n\nIn the example above we marked `header.logo` with `image_diff_validation` group but menu items and header text are marked with `image_diff_validation_blur` group. This means that different image specs will be applied to these elements. For header logo it will perform strict pixel-to-pixel comparison with 1 pixel denoise filter. And for the `image_diff_validation_blur` it will compare images with blur filter and offset analyzer making it less strict. You can change this behavior in settings and create your own image spec generators like this:\n\n```javascript\n$galen.settings.imageDiffSpecGenerators[\"image_diff_validation\"] = function (imagePath) {\n    return \"image file \" + imagePath + \", map-filter denoise 5, filter blur 2, error 5%\";\n};\n```\n\nIt is very important to specify the correct storage for each device. That is why in the example above we added `device.deviceName` to the storage path: `storage: \"image-diff/welcome-page-\" + device.deviceName`. This way the images for different devices will not be overwritten.\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgalenframework%2Fgalen-bootstrap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgalenframework%2Fgalen-bootstrap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgalenframework%2Fgalen-bootstrap/lists"}