Skip to content

Commit

Permalink
Merge branch 'develop' into jy14898/module-org
Browse files Browse the repository at this point in the history
  • Loading branch information
jy14898 committed Sep 23, 2022
2 parents b77d095 + 767e1f3 commit 37b455e
Show file tree
Hide file tree
Showing 35 changed files with 674 additions and 292 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -42,6 +42,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
### Changed

- Reorganised the library into new namespaces. Namely: library internals, tests, and examples are now under `Ctl.Internal.*`, `Test.Ctl.*`, and `Ctl.Examples.*` respectively. Documentation and comments have been updated to use these new names, but not entries of previous releases in the changelog. ([#1039](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1039))
- Switched to `preview` testnet by default ([#1030](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1030))

### Removed

Expand Down
34 changes: 13 additions & 21 deletions doc/e2e-testing.md
Expand Up @@ -23,33 +23,33 @@ The browser can be run headless (default) or headful (useful during test develop

Any programs that should be tested must be deployed and running on some testserver (e.g. with `make run-dev` for the included examples).

An executable for concrete tests is also needed. For a working example see `test/E2E.purs`.
An executable for concrete tests is also needed. For a working example see `test/E2E.purs`. It can be run conveniently using `./test/ctl-e2e-test.sh`.

## How to Run the Included Examples

The process is as follows:

1. Set `ps-entrypoint` in Makefile to `Ctl.Examples.ByURL`.
2. run `make run-dev`.
3. In another shell, run `make e2e-test`.
4. Examples will be run headless by default. In case of errors, the browser console will be printed to the console.
3. In another shell, run `./test/ctl-e2e-test.sh run`.
4. Examples will be run headless by default (pass `--no-headless` to inspect the browser window). In case of errors, the browser console output will be printed to the shell.

## Accepted Command Line Options

The provided test suite accepts some options. These can be passed via `make` after an additional double dash `--`, e.g. `make e2e-test -- --no-headless`. For usage examples, see the invocations in the `Makefile`, for a complete explanation, see `src/Contract/Test/E2E/Browser.purs`.
The provided test suite accepts some options. Run `./test/ctl-e2e-test.sh` for help. `run` command passes provided argument to the PS program. For a complete explanation, see `src/Contract/Test/E2E/Browser.purs`.

## How Wallets are Used

For purposes of testing, there are two parts to using a wallet: providing the right software version and importing a wallet with enough assets and a known password.

- The software just needs to be unpacked to some directory. This can either be the location where the browser unpacks it, or the result of unpacking a CRX file (see below).
- We provide the wallet data as tarballs which will be unpacked into the chrome profile before a test run.
- We provide the wallet data as a single tarball which will be unpacked into the chrome profile before a test run.

### How to Use a Different Version of a Wallet

Chrome extensions are unpacked to some directory by the browser. From there, they can either be used directly by the tests (which gives no control over upgrades and instead uses always the current version), or they can be repackaged as CRX files. The default setup provides CRX versions which `make e2e-test` automatically unpacks on each test run.
Chrome extensions are unpacked to some directory by the browser. From there, they can either be used directly by the tests (which gives no control over upgrades and instead uses always the current version), or they can be repackaged as CRX files. The default setup provides CRX versions which the script automatically unpacks on each test run.

The default test suite accepts the arguments `--nami-dir` and `--gero-dir` to point to the directories from which the extensions are loaded. (see the Makefile) In order to use the "live" version of an extension, just pass the arguments accordingly, e.g.:
The default test suite accepts the arguments of form `--nami-dir`, `--gero-dir`, etc., to point to the directories from which the extensions are loaded. In order to use the "live" version of an extension, just pass the arguments accordingly, e.g.:

```
@spago test --main Test.Ctl.E2E -a "E2ETest --nami-dir ~/.config/google-chrome/Default/Extensions/lpfcbjknijpeeillifnkikgncikgfhdo/ --gero-dir ~/.config/google-chrome/Default/Extensions/iifeegfcfhlhhnilhfoeihllenamcfgc --chrome-exe google-chome
Expand Down Expand Up @@ -78,24 +78,16 @@ The default test suite accepts the arguments `--nami-dir` and `--gero-dir` to po

We use `unzip` to unpack it. However, `unzip` will issue a warning because of extra bytes at the beginning, and will exit with a non-zero code, so the exit code needs to be ignored. (we use `|| echo to achieve that`).

See the `Makefile` for an example:

```
e2e-test-nami := test-data/chrome-extensions/nami_3.2.5_1.crx
unzip ${e2e-test-nami} -d ${e2e-temp-dir}/nami > /dev/zero || echo "ignore warnings"
```

`${e2e-temp-dir}/nami` can then be passed to the test suite as nami directory.

### How to Use a Different User Wallet

In the test suite, the wallet settings are just unpacked using `tar xzf ${e2e-test-nami-settings}` (see `Makefile`).
In the test suite, the wallet settings are just unpacked using `tar`.

A new settings tarball can be easily created, for example using the `Makefile`:
A new settings tarball can be easily created:

1. Adjust `${e2e-test-nami-settings}`, `${e2e-test-gero-settings}` and `${e2e-test-chrome-dir}` to point to where you want to store the settings and to chromes user-profile directory
2. Run `make e2e-run-browser-gero` or `make e2e-run-browser-nami` to fire up the test browser with one of the wallets loaded. Configure your wallet as usual.
3. Run `make nami-settings` or `make gero-settings` to store the settings to a tarball.
1. Run the browser with `./test/ctl-e2e-test.sh browser`
2. Set up a wallet extension, create and fund the wallet, and set the collateral.
3. Close the browser.
4. Run the script with `pack` argument. The file located at `test-data/settings.tar.gz` will be updated.

## How to Create Your Own Test Suite

Expand Down
1 change: 0 additions & 1 deletion examples/AlwaysMints.purs
Expand Up @@ -50,7 +50,6 @@ contract = do
example :: ConfigParams () -> Effect Unit
example cfg = launchAff_ $ do
runContract cfg contract

publishTestFeedback true

foreign import alwaysMints :: String
Expand Down
7 changes: 6 additions & 1 deletion examples/ByUrl.purs
Expand Up @@ -4,6 +4,7 @@ import Prelude

import Contract.Config
( ConfigParams
, testnetEternlConfig
, testnetFlintConfig
, testnetGeroConfig
, testnetLodeConfig
Expand Down Expand Up @@ -36,11 +37,12 @@ import Ctl.Examples.Wallet as Wallet
import Data.Array (last)
import Data.Foldable (lookup)
import Data.Maybe (Maybe(Just, Nothing))
import Data.Newtype (wrap)
import Data.String.Common (split)
import Data.String.Pattern (Pattern(Pattern))
import Data.Tuple.Nested (type (/\), (/\))
import Effect (Effect)
import Effect.Aff (launchAff_)
import Effect.Aff (delay, launchAff_)
import Effect.Class (liftEffect)
import Effect.Console as Console
import Effect.Exception (error)
Expand All @@ -62,6 +64,8 @@ main = do
config <- liftMaybe (error $ "unknown wallet name: " <> walletName) $
lookup walletName wallets
launchAff_ do
-- For Eternl, that does not initialize instantly
delay $ wrap 3000.0
paymentKey <- liftMaybe (error "Unable to load private key") $
privatePaymentKeyFromString paymentKeyStr
let
Expand All @@ -88,6 +92,7 @@ wallets =
[ "nami" /\ testnetNamiConfig
, "gero" /\ testnetGeroConfig
, "flint" /\ testnetFlintConfig
, "eternl" /\ testnetEternlConfig
, "lode" /\ testnetLodeConfig
, "nami-mock" /\ testnetNamiConfig
, "gero-mock" /\ testnetGeroConfig
Expand Down
9 changes: 5 additions & 4 deletions nix/runtime.nix
Expand Up @@ -2,9 +2,10 @@
rec {
defaultConfig = final: with final; {
inherit (inputs) cardano-configurations;
# { name = "preprod"; magic = 1; }
network = {
name = "preprod";
magic = 1; # use `null` for mainnet
name = "preview";
magic = 2; # use `null` for mainnet
};
node = {
port = 3001;
Expand Down Expand Up @@ -32,8 +33,8 @@ rec {
controlApiToken = "";
blockFetcher = {
firstBlock = {
slot = 5854109;
id = "85366c607a9777b887733de621aa2008aec9db4f3e6a114fb90ec2909bc06f14";
slot = 3162738;
id = "fed1bf7331a8f5dade0a6087b31218bb4552bdb722db450e4ecf66740395a93b";
};
autoStart = true;
startFromLast = false;
Expand Down
5 changes: 5 additions & 0 deletions package.json
Expand Up @@ -14,6 +14,11 @@
"integration-test": "spago run --main Test.Integration",
"unit-test": "spago run --main Ctl.Test.Unit",
"plutip-test": "spago run --main Test.Plutip",
"e2e-test": "./test/ctl-e2e-test.sh run",
"e2e-test-debug": "./test/ctl-e2e-test.sh run --no-headless",
"e2e-browser": "./test/ctl-e2e-test.sh browser",
"e2e-pack-settings": "./test/ctl-e2e-test.sh pack",
"e2e-unpack-settings": "./test/ctl-e2e-test.sh unpack",
"dev": "make run-dev",
"build": "make run-build"
},
Expand Down
32 changes: 21 additions & 11 deletions src/Contract/Address.purs
Expand Up @@ -62,9 +62,9 @@ import Ctl.Internal.Plutus.Types.TransactionUnspentOutput
( TransactionUnspentOutput
)
import Ctl.Internal.QueryM
( getWalletAddress
, ownPaymentPubKeyHash
, ownPubKeyHash
( getWalletAddresses
, ownPaymentPubKeyHashes
, ownPubKeyHashes
, ownStakePubKeyHash
) as QueryM
import Ctl.Internal.QueryM.NetworkId (getNetworkId) as QueryM
Expand Down Expand Up @@ -115,19 +115,22 @@ import Ctl.Internal.Types.UnbalancedTransaction
( PaymentPubKey(PaymentPubKey)
, ScriptOutput(ScriptOutput)
) as ExportUnbalancedTransaction
import Data.Array (head)
import Data.Maybe (Maybe)
import Data.Traversable (for, traverse)

-- | Get the `Address` of the browser wallet.
-- TODO: change this to Maybe (Array Address)
-- https://github.com/Plutonomicon/cardano-transaction-lib/issues/1045
getWalletAddress
:: forall (r :: Row Type). Contract r (Maybe Address)
getWalletAddress = do
mbAddr <- wrapContract $ QueryM.getWalletAddress
for mbAddr $
liftedM "getWalletAddress: failed to deserialize Address"
<<< wrapContract
<<< pure
<<< toPlutusAddress
mbAddr <- wrapContract $ (QueryM.getWalletAddresses <#> (_ >>= head))
for mbAddr
( liftedM "getWalletAddress: failed to deserialize address" <<< wrapContract
<<< pure
<<< toPlutusAddress
)

-- | Get the collateral of the browser wallet. This collateral will vary
-- | depending on the wallet.
Expand All @@ -148,12 +151,19 @@ getWalletCollateral = do
-- | Gets the wallet `PaymentPubKeyHash` via `getWalletAddress`.
ownPaymentPubKeyHash
:: forall (r :: Row Type). Contract r (Maybe PaymentPubKeyHash)
ownPaymentPubKeyHash = wrapContract QueryM.ownPaymentPubKeyHash
-- TODO: change this to Maybe (Array PaymentPubKeyHash)
-- https://github.com/Plutonomicon/cardano-transaction-lib/issues/1045
ownPaymentPubKeyHash = wrapContract
(QueryM.ownPaymentPubKeyHashes <#> (_ >>= head))

-- | Gets the wallet `PubKeyHash` via `getWalletAddress`.
ownPubKeyHash :: forall (r :: Row Type). Contract r (Maybe PubKeyHash)
ownPubKeyHash = wrapContract QueryM.ownPubKeyHash
-- TODO: change this to Maybe (Array PubKeyHash)
-- https://github.com/Plutonomicon/cardano-transaction-lib/issues/1045
ownPubKeyHash = wrapContract (QueryM.ownPubKeyHashes <#> (_ >>= head))

-- TODO: change this to Maybe (Array StakePubKeyHash)
-- https://github.com/Plutonomicon/cardano-transaction-lib/issues/1045
ownStakePubKeyHash :: forall (r :: Row Type). Contract r (Maybe StakePubKeyHash)
ownStakePubKeyHash = wrapContract QueryM.ownStakePubKeyHash

Expand Down
5 changes: 5 additions & 0 deletions src/Contract/Config.purs
Expand Up @@ -4,6 +4,7 @@ module Contract.Config
, testnetNamiConfig
, testnetGeroConfig
, testnetFlintConfig
, testnetEternlConfig
, testnetLodeConfig
, mainnetConfig
, mainnetNamiConfig
Expand Down Expand Up @@ -40,6 +41,7 @@ import Ctl.Internal.Wallet.Spec
, ConnectToNami
, ConnectToGero
, ConnectToFlint
, ConnectToEternl
, ConnectToLode
)
)
Expand Down Expand Up @@ -69,6 +71,9 @@ testnetGeroConfig = testnetConfig { walletSpec = Just ConnectToGero }
testnetFlintConfig :: ConfigParams ()
testnetFlintConfig = testnetConfig { walletSpec = Just ConnectToFlint }

testnetEternlConfig :: ConfigParams ()
testnetEternlConfig = testnetConfig { walletSpec = Just ConnectToEternl }

testnetLodeConfig :: ConfigParams ()
testnetLodeConfig = testnetConfig { walletSpec = Just ConnectToLode }

Expand Down
15 changes: 14 additions & 1 deletion src/Contract/Test/E2E/Browser.purs
Expand Up @@ -12,7 +12,7 @@ import Contract.Test.E2E.Helpers
)
import Contract.Test.E2E.WalletExt
( WalletConfig(WalletConfig)
, WalletExt(LodeExt, FlintExt, GeroExt, NamiExt)
, WalletExt(LodeExt, FlintExt, GeroExt, NamiExt, EternlExt)
)
import Data.Array (catMaybes)
import Data.Foldable (fold)
Expand Down Expand Up @@ -70,6 +70,18 @@ optParser = ado
, help "Chrome/-ium exe (search in env if not set)"
, value Nothing
]
eternlDir <- option (Just <$> str) $ fold
[ long "eternl-dir"
, metavar "DIR"
, help "Directory where Eternl is unpacked"
, value Nothing
]
eternlPassword <- option (Just <<< WalletPassword <$> str) $ fold
[ long "eternl-password"
, metavar "PW"
, help "Eternl wallet password"
, value Nothing
]
namiDir <- option (Just <$> str) $ fold
[ long "nami-dir"
, metavar "DIR"
Expand Down Expand Up @@ -135,6 +147,7 @@ optParser = ado
, mkConfig GeroExt geroDir geroPassword
, mkConfig FlintExt flintDir flintPassword
, mkConfig LodeExt lodeDir lodePassword
, mkConfig EternlExt eternlDir eternlPassword
]
in
TestOptions
Expand Down

0 comments on commit 37b455e

Please sign in to comment.