diff --git a/docs/command-line-arguments.md b/docs/command-line-arguments.md index 9c1ff68a..a11fb80c 100644 --- a/docs/command-line-arguments.md +++ b/docs/command-line-arguments.md @@ -13,41 +13,41 @@ Capture screenshots and compare them against the reference files. yarn loki test -- --port 9009 ``` -| Flag | Description | Default | -| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -| **`--host`** | Storybook host | `localhost` | -| **`--port`** | Storybook port | _None_ | -| **`--reactUri`** | URI to base of React Storybook. For static build use `file:./storybook-static`. | _None_ | -| **`--reactPort`** | React Storybook port | `6006` | -| **`--reactNativePort`** | React Native Storybook port | `7007` | -| **`--reference`** | Path to screenshot reference folder | `./.loki/reference` | -| **`--output`** | Path to screenshot output folder | `./.loki/current` | -| **`--difference`** | Path to image diff folder | `./.loki/difference` | -| **`--diffingEngine`** | What diffing engine to use, currently supported are `pixelmatch`, `looks-same` and `gm` | `pixelmatch` | -| **`--chromeAwsLambdaBatchSize`** | Number of stories to test per lambda invocation. | `1` | -| **`--chromeAwsLambdaBatchConcurrency`** | Number of stories to test in parallel per lambda invocation. | `1` | -| **`--chromeAwsLambdaFunctionName`** | Name of the use to capture screenshots. | `loki` | -| **`--chromeAwsLambdaRetries`** | The number of retries for invoking the lambda, in case of failure. | `0` | -| **`--chromeConcurrency`** | How many stories to test in parallel when using chrome | `4` | +| Flag | Description | Default | +| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | +| **`--host`** | Storybook host | `localhost` | +| **`--port`** | Storybook port | _None_ | +| **`--reactUri`** | URI to base of React Storybook. For static build use `file:./storybook-static`. | _None_ | +| **`--reactPort`** | React Storybook port | `6006` | +| **`--reactNativePort`** | React Native Storybook port | `7007` | +| **`--reference`** | Path to screenshot reference folder | `./.loki/reference` | +| **`--output`** | Path to screenshot output folder | `./.loki/current` | +| **`--difference`** | Path to image diff folder | `./.loki/difference` | +| **`--diffingEngine`** | What diffing engine to use, currently supported are `pixelmatch`, `looks-same` and `gm` | `pixelmatch` | +| **`--chromeAwsLambdaBatchSize`** | Number of stories to test per lambda invocation. | `1` | +| **`--chromeAwsLambdaBatchConcurrency`** | Number of stories to test in parallel per lambda invocation. | `1` | +| **`--chromeAwsLambdaFunctionName`** | Name of the use to capture screenshots. | `loki` | +| **`--chromeAwsLambdaRetries`** | The number of retries for invoking the lambda, in case of failure. | `0` | +| **`--chromeConcurrency`** | How many stories to test in parallel when using chrome | `4` | | **`--chromeDockerImage`** | What docker image to use when running chrome | `yukinying/chrome-headless-browser-stable:100.0.4896.127` | -| **`--chromeDockerWithoutSeccomp`** | Run chrome docker without custom seccomp settings. | `false` | -| **`--chromeDockerUseCopy`** | Use docker copy instead of volume mount for local stories | `false` | -| **`--chromeEnableAnimations`** | Enable CSS transitions and animations. | `false` | -| **`--chromeFlags`** | Custom chrome flags. | `--headless --disable-gpu --hide-scrollbars` | -| **`--chromeLoadTimeout`** | How many miliseconds loki will wait for the page to load before taking as screnshot. | `60000` | -| **`--chromeRetries`** | The number of retries for taking the screenshot, in case of failure. | `0` | -| **`--chromeSelector`** | CSS selector to the part of the DOM to screenshot. Useful you have decorators that should be excluded. | `#root > *` | -| **`--chromeTolerance`** | How many percent tolerated difference compared to reference image. Behaviour of tolerance depends on `diffingEngine`. | `0` | -| **`--chromeEmulatedMedia`** | Emulates the given media for CSS media queries. Set to `print` to test print styles. | _None_ | -| **`--skipStories`** | **DEPRECATED** Regular expression for stories that should not be tested, it will be tested against a string with the format `${kind} ${story}`. | _None_ | -| **`--storiesFilter`** | Opposite of `--skipStories`. | _None_ | -| **`--configurationFilter`** | Regular expression for targets that should be tested. | _None_ | -| **`--targetFilter`** | Regular expression for targets that should be tested. | _None_ | -| **`--requireReference`** | Fail stories without reference image, useful for CI. | _False, true for CI_ | -| **`--verboseRenderer`** | Plain text renderer, useful for CI. | _False, true for CI_ | -| **`--silent`** | Plain text renderer that will only output errors. | `false` | -| **`--dockerWithSudo`** | Run docker commands with sudo. | `false` | -| **`--dockerNet`** | Argument to pass to docker --net, e.g. `host` or `bridge`. | _None_ | +| **`--chromeDockerWithoutSeccomp`** | Run chrome docker without custom seccomp settings. | `false` | +| **`--chromeDockerUseCopy`** | Use docker copy instead of volume mount for local stories | `false` | +| **`--chromeEnableAnimations`** | Enable CSS transitions and animations. | `false` | +| **`--chromeFlags`** | Custom chrome flags. | `--headless --disable-gpu --hide-scrollbars` | +| **`--chromeLoadTimeout`** | How many miliseconds loki will wait for the page to load before taking as screnshot. | `60000` | +| **`--chromeRetries`** | The number of retries for taking the screenshot, in case of failure. | `0` | +| **`--chromeSelector`** | CSS selector to the part of the DOM to screenshot. Useful you have decorators that should be excluded. | `#root > *` | +| **`--chromeTolerance`** | How many percent tolerated difference compared to reference image. Behaviour of tolerance depends on `diffingEngine`. | `0` | +| **`--chromeEmulatedMedia`** | Emulates the given media for CSS media queries. Set to `print` to test print styles. | _None_ | +| **`--skipStories`** | **DEPRECATED** Regular expression for stories that should not be tested, it will be tested against a string with the format `${kind} ${story}`. | _None_ | +| **`--storiesFilter`** | Opposite of `--skipStories`. | _None_ | +| **`--configurationFilter`** | Regular expression for targets that should be tested. | _None_ | +| **`--targetFilter`** | Regular expression for targets that should be tested. | _None_ | +| **`--requireReference`** | Fail stories without reference image, useful for CI. | _False, true for CI_ | +| **`--verboseRenderer`** | Plain text renderer, useful for CI. | _False, true for CI_ | +| **`--silent`** | Plain text renderer that will only output errors. | `false` | +| **`--dockerWithSudo`** | Run docker commands with sudo. | `false` | +| **`--dockerNet`** | Argument to pass to docker --net, e.g. `host` or `bridge`. | _None_ | ## `loki update` diff --git a/docs/configuration.md b/docs/configuration.md index c348288f..cc3686da 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -112,17 +112,18 @@ module.exports = { ## `configurations` -| Name | Type | Description | Targets | -| ------------------------------------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | -| **`target`** | _string_ | Target platform, possible values are `chrome.app`, `chrome.docker`, `chrome.aws-lambda`, `ios.simulator`, `android.emulator`. | All | -| **`skipStories`** | _string_ | **DEPRECATED** Same as `loki.skipStories`, but applied to only this configuration. | All | -| **`storiesFilter`** | _string_ | Same as `loki.storiesFilter`, but applied to only this configuration. | All | -| **`chromeSelector`** | _string_ | Same as `loki.chromeSelector`, but applied to only this configuration. | `chrome.*` | -| **`preset`** | _string_ | Predefined bundled configuration, possible values are `Retina Macbook Pro 15`, `iPhone 7`, `iPhone 5`, `Google Pixel`, `A4 Paper`, and `US Letter Paper`. | `chrome.*` | -| **`userAgent`** | _string_ | Custom user agent. | `chrome.*` | -| **`width`** | _integer_ | Browser viewport width. | `chrome.*` | -| **`height`** | _integer_ | Browser viewport height. | `chrome.*` | -| **`disableAutomaticViewportHeight`** | _boolean_ | If the content goes below the viewport do not increase the height so that it fits. | `chrome.*` | -| **`deviceScaleFactor`** | _integer_ | Browser pixel density multiple, use `2` for retina, not supported in docker. | `chrome.app` | -| **`mobile`** | _boolean_ | Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text autosizing and more. | `chrome.*` | -| **`media`** | _string_ | Emulates the given media for CSS media queries. | _None_ | +| Name | Type | Description | Targets | +| ------------------------------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ | +| **`target`** | _string_ | Target platform, possible values are `chrome.app`, `chrome.docker`, `chrome.aws-lambda`, `ios.simulator`, `android.emulator`. | All | +| **`skipStories`** | _string_ | **DEPRECATED** Same as `loki.skipStories`, but applied to only this configuration. | All | +| **`storiesFilter`** | _string_ | Same as `loki.storiesFilter`, but applied to only this configuration. | All | +| **`chromeSelector`** | _string_ | Same as `loki.chromeSelector`, but applied to only this configuration. | `chrome.*` | +| **`preset`** | _string_ | Predefined bundled configuration, possible values are `Retina Macbook Pro 15`, `Retina Macbook Pro 15 Dark Mode`, `iPhone 7`, `iPhone 7 Dark Mode`, `iPhone 5`, `iPhone 5 Dark Mode`, `Google Pixel`, `Google Pixel Dark Mode`, `A4 Paper`, and `US Letter Paper`. | `chrome.*` | +| **`userAgent`** | _string_ | Custom user agent. | `chrome.*` | +| **`width`** | _integer_ | Browser viewport width. | `chrome.*` | +| **`height`** | _integer_ | Browser viewport height. | `chrome.*` | +| **`disableAutomaticViewportHeight`** | _boolean_ | If the content goes below the viewport do not increase the height so that it fits. | `chrome.*` | +| **`deviceScaleFactor`** | _integer_ | Browser pixel density multiple, use `2` for retina, not supported in docker. | `chrome.app` | +| **`mobile`** | _boolean_ | Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text autosizing and more. | `chrome.*` | +| **`media`** | _string_ | Emulates the given media for CSS media queries. | _None_ | +| **`features`** | _array_ | Emulates the given features for CSS media queries. See [setEmulatedMedia docs](https://chromedevtools.github.io/devtools-protocol/tot/Emulation/#method-setEmulatedMedia) | `chrome.*` | diff --git a/examples/react/.loki/reference/chrome_a4_Media_with_dark_scheme_queries.png b/examples/react/.loki/reference/chrome_a4_Media_with_dark_scheme_queries.png new file mode 100644 index 00000000..cc1f2f50 Binary files /dev/null and b/examples/react/.loki/reference/chrome_a4_Media_with_dark_scheme_queries.png differ diff --git a/examples/react/.loki/reference/chrome_a4_Media_with_light_scheme_queries.png b/examples/react/.loki/reference/chrome_a4_Media_with_light_scheme_queries.png new file mode 100644 index 00000000..00ab3d01 Binary files /dev/null and b/examples/react/.loki/reference/chrome_a4_Media_with_light_scheme_queries.png differ diff --git a/examples/react/.loki/reference/chrome_iphone7_Media_with_dark_scheme_queries.png b/examples/react/.loki/reference/chrome_iphone7_Media_with_dark_scheme_queries.png new file mode 100644 index 00000000..4b30a3cb Binary files /dev/null and b/examples/react/.loki/reference/chrome_iphone7_Media_with_dark_scheme_queries.png differ diff --git a/examples/react/.loki/reference/chrome_iphone7_Media_with_light_scheme_queries.png b/examples/react/.loki/reference/chrome_iphone7_Media_with_light_scheme_queries.png new file mode 100644 index 00000000..5badaa31 Binary files /dev/null and b/examples/react/.loki/reference/chrome_iphone7_Media_with_light_scheme_queries.png differ diff --git a/examples/react/.loki/reference/chrome_laptop_Media_with_dark_scheme_queries.png b/examples/react/.loki/reference/chrome_laptop_Media_with_dark_scheme_queries.png new file mode 100644 index 00000000..c110faf1 Binary files /dev/null and b/examples/react/.loki/reference/chrome_laptop_Media_with_dark_scheme_queries.png differ diff --git a/examples/react/.loki/reference/chrome_laptop_Media_with_light_scheme_queries.png b/examples/react/.loki/reference/chrome_laptop_Media_with_light_scheme_queries.png new file mode 100644 index 00000000..182fffee Binary files /dev/null and b/examples/react/.loki/reference/chrome_laptop_Media_with_light_scheme_queries.png differ diff --git a/examples/react/src/api/Media.stories.js b/examples/react/src/api/Media.stories.js index ab6672a4..4263b3fa 100644 --- a/examples/react/src/api/Media.stories.js +++ b/examples/react/src/api/Media.stories.js @@ -8,4 +8,25 @@ export default { export const MediaAwareComponent = () => (
); + MediaAwareComponent.storyName = 'with media queries'; + +export const LightSchemeComponent = () => ( + +); + +LightSchemeComponent.parameters = { + loki: { features: [{ name: 'prefers-color-scheme', value: 'light' }] }, +}; + +LightSchemeComponent.storyName = 'with light scheme queries'; + +export const DarkSchemeComponent = () => ( + +); + +DarkSchemeComponent.parameters = { + loki: { features: [{ name: 'prefers-color-scheme', value: 'dark' }] }, +}; + +DarkSchemeComponent.storyName = 'with dark scheme queries'; diff --git a/examples/react/src/api/MediaAwareComponent.css b/examples/react/src/api/MediaAwareComponent.css index 9a9c6039..20abe1b2 100644 --- a/examples/react/src/api/MediaAwareComponent.css +++ b/examples/react/src/api/MediaAwareComponent.css @@ -9,3 +9,15 @@ content: 'Media: print'; } } + +@media (prefers-color-scheme: light) { + .FeaturesAwareComponent:before { + content: 'Features: prefers-color-scheme:light'; + } +} + +@media (prefers-color-scheme: dark) { + .FeaturesAwareComponent:before { + content: 'Features: prefers-color-scheme:dark'; + } +} diff --git a/packages/target-chrome-core/src/create-chrome-target.js b/packages/target-chrome-core/src/create-chrome-target.js index b03d8ad2..69878eff 100644 --- a/packages/target-chrome-core/src/create-chrome-target.js +++ b/packages/target-chrome-core/src/create-chrome-target.js @@ -74,8 +74,19 @@ function createChromeTarget( await Network.clearBrowserCookies(); } await Emulation.setDeviceMetricsOverride(deviceMetrics); - if (options.media) { - await Emulation.setEmulatedMedia({ media: options.media }); + + if (options.media || options.features) { + const emulated = {}; + + if (options.media) { + emulated.media = options.media; + } + + if (options.features) { + emulated.features = options.features; + } + + await Emulation.setEmulatedMedia(emulated); } const pendingRequestURLMap = {}; @@ -376,7 +387,8 @@ function createChromeTarget( media: options.chromeEmulatedMedia, fetchFailIgnore: options.fetchFailIgnore, }, - configuration + configuration, + parameters.loki || {} ); if (configuration.preset) { if (!presets[configuration.preset]) { diff --git a/packages/target-chrome-core/src/presets.json b/packages/target-chrome-core/src/presets.json index 37e2b2bf..0f7cf01a 100644 --- a/packages/target-chrome-core/src/presets.json +++ b/packages/target-chrome-core/src/presets.json @@ -27,6 +27,38 @@ "deviceScaleFactor": 2, "mobile": false }, + "Retina Macbook Pro 15 Dark Mode": { + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36", + "width": 1440, + "height": 900, + "deviceScaleFactor": 2, + "mobile": false, + "features": [{ "name": "prefers-color-scheme", "value": "dark" }] + }, + "iPhone 7 Dark Mode": { + "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2_1 like Mac OS X) AppleWebKit/602.4.6 (KHTML, like Gecko) Version/10.0 Mobile/14D27 Safari/602.1", + "width": 375, + "height": 667, + "deviceScaleFactor": 2, + "mobile": false, + "features": [{ "name": "prefers-color-scheme", "value": "dark" }] + }, + "iPhone 5 Dark Mode": { + "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3", + "width": 320, + "height": 568, + "deviceScaleFactor": 2, + "mobile": false, + "features": [{ "name": "prefers-color-scheme", "value": "dark" }] + }, + "Google Pixel Dark Mode": { + "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Pixel Build/NMF26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36", + "width": 360, + "height": 640, + "deviceScaleFactor": 2, + "mobile": false, + "features": [{ "name": "prefers-color-scheme", "value": "dark" }] + }, "A4 Paper": { "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36", "width": 595,