-
-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First version of sydtest-webdriver, sydtest-webdriver-yesod and sydte…
…st-webdriver-screenshot
- Loading branch information
Tom Sydney Kerckhove
committed
Apr 19, 2022
1 parent
9265dba
commit 824fcc5
Showing
28 changed files
with
951 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
{ lib | ||
, stdenv | ||
, libxslt | ||
, fontconfig | ||
, lndir | ||
, roboto | ||
, twitter-color-emoji | ||
}: | ||
|
||
# Chromium reads FONTCONFIG_SYSROOT, and uses that instead of / for all font-related filepaths | ||
# Chromium also reads FONTCONFIG_PATH, but always also reads FONTCONFIG_SYSROOT/etc/fonts/font.conf so you cannot override fonts, only add to them | ||
# so here we have to nix build of something that looks like / with everything font-related, (which I could only do based on the strace output showing me which things it tries to read in FONTCONFIG_SYSROOT) | ||
# and then set FONTCONFIG_SYSROOT to that. | ||
# and I only found FONTCONFIG_SYSROOT by looking through the chromium source code | ||
let | ||
fonts = { | ||
"roboto" = roboto; | ||
"twitter" = twitter-color-emoji; | ||
}; | ||
fontNames = builtins.attrNames fonts; | ||
in | ||
stdenv.mkDerivation { | ||
name = "fonts-config"; | ||
unpackPhase = "true"; | ||
nativeBuildInputs = [ libxslt lndir ]; | ||
buildInputs = [ fontconfig ]; | ||
inherit fontNames; | ||
installPhase = | ||
let singleDir = name: fontPkg: '' | ||
echo ${fontPkg} | ||
ln -s ${fontPkg} $out/etc/fonts/${name} | ||
''; | ||
in | ||
'' | ||
mkdir -p $out/etc/fonts | ||
${lib.concatStringsSep "\n" (lib.mapAttrsToList singleDir fonts)} | ||
mkdir -p $out/fonts | ||
xsltproc \ | ||
--stringparam fontNames "$fontNames" \ | ||
--path ${fontconfig.out}/share/xml/fontconfig \ | ||
${./fonts.xsl} ${fontconfig.out}/etc/fonts/fonts.conf \ | ||
> $out/etc/fonts/fonts.conf | ||
''; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?xml version="1.0"?> | ||
|
||
<!-- | ||
This is an adaptation of https://github.com/NixOS/nixpkgs/blob/068984c00e0d4e54b6684d98f6ac47c92dcb642e/pkgs/development/libraries/fontconfig/make-fonts-conf.xsl | ||
--> | ||
|
||
<xsl:stylesheet version="1.0" | ||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | ||
xmlns:str="http://exslt.org/strings" | ||
extension-element-prefixes="str" | ||
> | ||
|
||
|
||
<xsl:param name="fontNames" /> | ||
|
||
<xsl:template match="/fontconfig"> | ||
|
||
<fontconfig> | ||
<cachedir prefix="xdg">fontconfig</cachedir> | ||
|
||
|
||
<xsl:for-each select="str:tokenize($fontNames)"> | ||
<dir>/etc/fonts/<xsl:value-of select="." />/share/fonts</dir> | ||
<xsl:text>
</xsl:text> | ||
</xsl:for-each> | ||
</fontconfig> | ||
|
||
</xsl:template> | ||
|
||
</xsl:stylesheet> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,25 @@ | ||
let | ||
pkgs = import ./nix/pkgs.nix { }; | ||
pre-commit = import ./nix/pre-commit.nix; | ||
fontconfigDir = pkgs.callPackage ./nix/fonts-conf.nix { }; | ||
in | ||
pkgs.haskell.lib.buildStackProject { | ||
name = "sydtest-shell"; | ||
buildInputs = with pkgs; [ | ||
chromedriver | ||
chromium | ||
coreutils | ||
mongodb | ||
niv | ||
postgresql | ||
rabbitmq-server | ||
redis | ||
selenium-server-standalone | ||
zlib | ||
] ++ pre-commit.tools; | ||
shellHook = '' | ||
export TMPDIR=/tmp | ||
${pre-commit.check.shellHook} | ||
export FONTCONFIG_SYSROOT=${fontconfigDir} | ||
''; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
screenshot-comparison |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
name: sydtest-webdriver-screenshot | ||
version: 0.0.0.0 | ||
|
||
dependencies: | ||
- base >= 4.7 && < 5 | ||
|
||
library: | ||
source-dirs: src | ||
dependencies: | ||
- JuicyPixels | ||
- bytestring | ||
- http-types | ||
- mtl | ||
- network-uri | ||
- path | ||
- path-io | ||
- sydtest | ||
- sydtest-wai | ||
- sydtest-webdriver | ||
- webdriver | ||
|
||
tests: | ||
sydtest-webdriver-screenshot-test: | ||
main: Spec.hs | ||
source-dirs: test | ||
build-tools: sydtest-discover | ||
ghc-options: | ||
- -threaded | ||
- -rtsopts | ||
- -with-rtsopts=-N | ||
dependencies: | ||
- http-types | ||
- network-uri | ||
- sydtest | ||
- sydtest-wai | ||
- sydtest-webdriver | ||
- sydtest-webdriver-screenshot | ||
- wai |
90 changes: 90 additions & 0 deletions
90
sydtest-webdriver-screenshot/src/Test/Syd/Webdriver/Screenshot.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
{-# LANGUAGE DataKinds #-} | ||
{-# LANGUAGE FlexibleContexts #-} | ||
{-# LANGUAGE FlexibleInstances #-} | ||
{-# LANGUAGE OverloadedStrings #-} | ||
{-# LANGUAGE ScopedTypeVariables #-} | ||
{-# LANGUAGE TypeFamilies #-} | ||
{-# LANGUAGE UndecidableInstances #-} | ||
-- Because of webdriver using dangerous constructors | ||
{-# OPTIONS_GHC -fno-warn-incomplete-record-updates #-} | ||
-- For the undefined trick | ||
{-# OPTIONS_GHC -fno-warn-unused-pattern-binds #-} | ||
|
||
module Test.Syd.Webdriver.Screenshot where | ||
|
||
import Codec.Picture as Picture | ||
import Control.Monad.Reader | ||
import qualified Data.ByteString as SB | ||
import qualified Data.ByteString.Lazy as LB | ||
import Path | ||
import Path.IO | ||
import System.Exit | ||
import Test.Syd | ||
import Test.Syd.Webdriver | ||
import Test.WebDriver as WD | ||
|
||
-- | A screenshot with location | ||
data Screenshot = Screenshot | ||
{ -- | File location for comparisons | ||
screenshotFile :: !(Path Abs File), | ||
-- | Decoded image | ||
screenshotImage :: !(Picture.Image PixelRGB8) | ||
} | ||
|
||
-- | Take a screenshot and turn it into a golden test. | ||
goldenScreenshotHere :: FilePath -> WebdriverTestM app (GoldenTest Screenshot) | ||
goldenScreenshotHere fp = pureGoldenScreenshot fp <$> WD.screenshot | ||
|
||
-- | Make a golden test for a given screenshot in lazy 'LB.ByteString' form. | ||
pureGoldenScreenshot :: FilePath -> LB.ByteString -> GoldenTest Screenshot | ||
pureGoldenScreenshot fp contents = | ||
GoldenTest | ||
{ goldenTestRead = do | ||
relFile <- parseRelFile fp | ||
currentDir <- getCurrentDir | ||
let resolvedFile = currentDir </> relFile | ||
mContents <- forgivingAbsence $ SB.readFile $ fromAbsFile resolvedFile | ||
forM mContents $ \cts -> do | ||
case decodePng cts of | ||
Left err -> die err | ||
Right dynamicImage -> | ||
pure $ | ||
Screenshot | ||
{ screenshotFile = resolvedFile, | ||
screenshotImage = convertRGB8 dynamicImage | ||
}, | ||
goldenTestProduce = do | ||
let sb = LB.toStrict contents | ||
case decodePng sb of | ||
Left err -> expectationFailure $ "Could not parse screenshot as png: " <> err | ||
Right dynamicImage -> do | ||
let image = convertRGB8 dynamicImage | ||
relFile <- parseRelFile fp | ||
tempDir <- resolveDir' "screenshot-comparison" | ||
let tempFile = tempDir </> relFile | ||
ensureDir $ parent tempFile | ||
-- Write it to a file so we can compare it if it differs. | ||
writePng (fromAbsFile tempFile) image | ||
pure $ | ||
Screenshot | ||
{ screenshotFile = tempFile, | ||
screenshotImage = image | ||
}, | ||
goldenTestWrite = \(Screenshot _ actual) -> do | ||
relFile <- parseRelFile fp | ||
currentDir <- getCurrentDir | ||
let resolvedFile = currentDir </> relFile | ||
ensureDir $ parent resolvedFile | ||
writePng (fromAbsFile resolvedFile) actual, | ||
goldenTestCompare = \(Screenshot actualPath actual) (Screenshot expectedPath expected) -> | ||
if actual == expected | ||
then Nothing | ||
else | ||
Just $ | ||
ExpectationFailed $ | ||
unlines | ||
[ "Screenshots differ.", | ||
"expected: " <> fromAbsFile expectedPath, | ||
"actual: " <> fromAbsFile actualPath | ||
] | ||
} |
54 changes: 54 additions & 0 deletions
54
sydtest-webdriver-screenshot/sydtest-webdriver-screenshot.cabal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
cabal-version: 1.12 | ||
|
||
-- This file has been generated from package.yaml by hpack version 0.34.6. | ||
-- | ||
-- see: https://github.com/sol/hpack | ||
|
||
name: sydtest-webdriver-screenshot | ||
version: 0.0.0.0 | ||
build-type: Simple | ||
|
||
library | ||
exposed-modules: | ||
Test.Syd.Webdriver.Screenshot | ||
other-modules: | ||
Paths_sydtest_webdriver_screenshot | ||
hs-source-dirs: | ||
src | ||
build-depends: | ||
JuicyPixels | ||
, base >=4.7 && <5 | ||
, bytestring | ||
, http-types | ||
, mtl | ||
, network-uri | ||
, path | ||
, path-io | ||
, sydtest | ||
, sydtest-wai | ||
, sydtest-webdriver | ||
, webdriver | ||
default-language: Haskell2010 | ||
|
||
test-suite sydtest-webdriver-screenshot-test | ||
type: exitcode-stdio-1.0 | ||
main-is: Spec.hs | ||
other-modules: | ||
Test.Syd.Webdriver.Screenshot.App | ||
Test.Syd.Webdriver.ScreenshotSpec | ||
Paths_sydtest_webdriver_screenshot | ||
hs-source-dirs: | ||
test | ||
ghc-options: -threaded -rtsopts -with-rtsopts=-N | ||
build-tool-depends: | ||
sydtest-discover:sydtest-discover | ||
build-depends: | ||
base >=4.7 && <5 | ||
, http-types | ||
, network-uri | ||
, sydtest | ||
, sydtest-wai | ||
, sydtest-webdriver | ||
, sydtest-webdriver-screenshot | ||
, wai | ||
default-language: Haskell2010 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{-# OPTIONS_GHC -F -pgmF sydtest-discover #-} |
14 changes: 14 additions & 0 deletions
14
sydtest-webdriver-screenshot/test/Test/Syd/Webdriver/Screenshot/App.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{-# LANGUAGE OverloadedStrings #-} | ||
|
||
module Test.Syd.Webdriver.Screenshot.App where | ||
|
||
import Network.HTTP.Types as HTTP | ||
import Network.Wai as Wai | ||
|
||
exampleApplication :: Wai.Application | ||
exampleApplication req sendResp = | ||
sendResp $ | ||
responseLBS | ||
HTTP.ok200 | ||
(requestHeaders req) | ||
"<html><body><h1>Hello World</h1><h2>Foo</h2><h3>Bar</h3><h4>Quux</h4></body></html>" |
22 changes: 22 additions & 0 deletions
22
sydtest-webdriver-screenshot/test/Test/Syd/Webdriver/ScreenshotSpec.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
module Test.Syd.Webdriver.ScreenshotSpec (spec) where | ||
|
||
import Network.URI | ||
import Test.Syd | ||
import Test.Syd.Wai | ||
import Test.Syd.Webdriver | ||
import Test.Syd.Webdriver.Screenshot | ||
import Test.Syd.Webdriver.Screenshot.App | ||
|
||
spec :: Spec | ||
spec = exampleAppSpec $ do | ||
it "can make a screenshot of home" $ do | ||
openPath "/" | ||
goldenScreenshotHere "test_resources/home.png" | ||
|
||
exampleAppSpec :: WebdriverSpec () -> Spec | ||
exampleAppSpec = webdriverSpec $ \_ -> do | ||
portNumber <- applicationSetupFunc exampleApplication | ||
let uriStr = "http://127.0.0.1:" <> show portNumber | ||
case parseURI uriStr of | ||
Nothing -> liftIO $ expectationFailure $ "Failed to parse uri as string: " <> show uriStr | ||
Just uri -> pure (uri, ()) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.