@12-apps/payments-e2e 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +67 -4
  2. package/dist/globs.d.ts +26 -0
  3. package/dist/globs.d.ts.map +1 -1
  4. package/dist/globs.js +26 -0
  5. package/dist/globs.js.map +1 -1
  6. package/dist/index.d.ts +9 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +9 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/platform-world.d.ts +78 -0
  11. package/dist/platform-world.d.ts.map +1 -0
  12. package/dist/platform-world.js +24 -0
  13. package/dist/platform-world.js.map +1 -0
  14. package/dist/steps/activation.steps.d.ts +2 -0
  15. package/dist/steps/activation.steps.d.ts.map +1 -0
  16. package/dist/steps/activation.steps.js +74 -0
  17. package/dist/steps/activation.steps.js.map +1 -0
  18. package/dist/steps/carteira.steps.js +19 -0
  19. package/dist/steps/carteira.steps.js.map +1 -1
  20. package/dist/steps/saved-card-wallet.steps.d.ts +2 -0
  21. package/dist/steps/saved-card-wallet.steps.d.ts.map +1 -0
  22. package/dist/steps/saved-card-wallet.steps.js +65 -0
  23. package/dist/steps/saved-card-wallet.steps.js.map +1 -0
  24. package/dist/steps-platform/plataforma.steps.d.ts +2 -0
  25. package/dist/steps-platform/plataforma.steps.d.ts.map +1 -0
  26. package/dist/steps-platform/plataforma.steps.js +78 -0
  27. package/dist/steps-platform/plataforma.steps.js.map +1 -0
  28. package/dist/world.d.ts +33 -0
  29. package/dist/world.d.ts.map +1 -1
  30. package/dist/world.js.map +1 -1
  31. package/features/activating-a-provider.feature +29 -0
  32. package/features/comprando-com-apple-pay.feature +25 -0
  33. package/features/saving-a-card.feature +29 -0
  34. package/features-platform/a-aplicacao-que-as-lojas-autorizam.feature +23 -0
  35. package/features-platform/a-homologacao-e-da-plataforma.feature +31 -0
  36. package/package.json +4 -3
package/README.md CHANGED
@@ -4,9 +4,10 @@ The buyer journeys for the payments checkout, as Gherkin you run **against your
4
4
  own app**.
5
5
 
6
6
  Mounting `createPaymentFlows` gives you a checkout. This gives you its
7
- end-to-end coverage: twenty scenarios across seven features — PIX, card, hosted
8
- hand-off and return, provider failover, issuer declines, an unresolved charge, a
9
- store that cannot charge at all, and per-provider screens. You implement one
7
+ end-to-end coverage: twenty-seven scenarios across ten features — PIX, card,
8
+ digital wallets, hosted hand-off and return, provider failover, issuer
9
+ declines, an unresolved charge, a store that cannot charge at all,
10
+ per-provider screens, and saving a card outside checkout. You implement one
10
11
  port and add three lines of config. Nothing is copied, so a scenario added here
11
12
  later runs in your app on the next version bump.
12
13
 
@@ -84,12 +85,33 @@ files do not change either way.
84
85
  `pix-only` · `card` · `both-methods` · `hosted` · `awaiting` · `settles` ·
85
86
  `declined` · `unresolved` · `unavailable` · `no-provider` ·
86
87
  `no-provider-remedy` · `payments-off` · `two-mintable` · `redirect-head` ·
87
- `google-pay` · `screen-on-page` · `screen-handoff` · `screen-undeclared` ·
88
+ `google-pay` · `apple-pay` · `apple-pay-unsupported` · `wallet` ·
89
+ `activation` · `screen-on-page` · `screen-handoff` · `screen-undeclared` ·
88
90
  `screen-unknown`
89
91
 
90
92
  Adding a member is a breaking change for hosts, deliberately: a scenario needing
91
93
  a store nobody can build is a scenario that silently never runs.
92
94
 
95
+ `wallet` (added for FUT-183/FUT-478) is one of two members that are **not a
96
+ checkout**: `open(page, 'wallet')` must land the buyer on the package's
97
+ manage-cards surface (`screens.ManageCards` from `createPaymentFlows`) at a
98
+ store whose single provider can vault — the chain head declares the adapter
99
+ `vault` seam, the connection runs in stub mode, and the wallet starts empty.
100
+ The journey types the shared `DECLINE_PAN` for the refusal path, so no store
101
+ flag decides the outcome; the card does. Hosts upgrading across this version
102
+ must add the member to their `open` mapping or their world stops compiling —
103
+ which is the point.
104
+
105
+ `activation` (added for FUT-689) is the other, and the first **admin**-side
106
+ shape: `open(page, 'activation')` must land the OWNER on the settings panel of
107
+ one provider that declares `activationCharge`, connected in stub mode and
108
+ never charged — the sales switch starts locked off. The host's
109
+ `renderVerification` slot must render the shared card form plus the
110
+ `activation-*` test ids `src/steps/activation.steps.ts` documents (pay button,
111
+ outcome, refund line, and the raw enable-attempt probe pair). As in `wallet`,
112
+ the typed card decides the outcome: `DECLINE_PAN` is refused with a named
113
+ reason, anything else pays the cent and gets it refunded.
114
+
93
115
  ## Why this package ships compiled JavaScript
94
116
 
95
117
  Its siblings export raw `.ts` through their `exports` map, because an
@@ -103,6 +125,47 @@ does not rescue them either; it skips `node_modules` by design.
103
125
  Shipping source here would produce a package that type-checks, publishes,
104
126
  installs, and then throws on your first test run.
105
127
 
128
+ ## The platform-operations journeys (opt-in)
129
+
130
+ The buyer journeys above run in any app that mounts the checkout. A second,
131
+ **separate** set covers the app that operates the PLATFORM — the
132
+ Connect-application consult screen and the platform homologação
133
+ (`ConnectApplicationPanel` / `PlatformHomologacao` from
134
+ `@12-apps/payments-frontend`). Most checkout consumers have no such surface,
135
+ so these ship behind their own port and glob triple: nothing about them lands
136
+ in `paymentsFeatures` or `paymentsSteps`, and a host that never lists them is
137
+ untouched.
138
+
139
+ ```ts
140
+ // tests/e2e/steps/platform-world.ts — inside your super-admin steps glob
141
+ import { definePaymentsPlatformWorld } from '@12-apps/payments-e2e';
142
+
143
+ definePaymentsPlatformWorld({
144
+ openConnectApplication: async (page, shape) => { /* sign in + route */ },
145
+ openHomologacao: async (page, shape) => { /* sign in + produce the shape */ },
146
+ });
147
+ ```
148
+
149
+ ```ts
150
+ import {
151
+ paymentsPlatformFeatures,
152
+ paymentsPlatformFeaturesRoot,
153
+ paymentsPlatformSteps,
154
+ } from '@12-apps/payments-e2e';
155
+
156
+ defineBddConfig({
157
+ features: [paymentsPlatformFeatures],
158
+ featuresRoot: paymentsPlatformFeaturesRoot,
159
+ steps: [paymentsPlatformSteps, 'tests/e2e/steps/**/*.ts'],
160
+ outputDir: '.features-gen/platform',
161
+ });
162
+ ```
163
+
164
+ The same three silent failures apply verbatim — use the exported globs, set
165
+ `featuresRoot`, assert your scenario count. And `openHomologacao` must
166
+ PRODUCE its shape, not just navigate: one scenario records an outcome, so a
167
+ later `unrequested` opening has to clear it again.
168
+
106
169
  ## Writing your own specs in the same vocabulary
107
170
 
108
171
  The buyer gestures are exported too, so hand-written specs beside the journeys
package/dist/globs.d.ts CHANGED
@@ -40,4 +40,30 @@ export declare const paymentsFeaturesRoot: string;
40
40
  * in every worker.
41
41
  */
42
42
  export declare const paymentsSteps: string;
43
+ /**
44
+ * The PLATFORM-OPERATIONS journeys (FUT-479 / FUT-483, packaged by FUT-573),
45
+ * as a SEPARATE opt-in glob triple.
46
+ *
47
+ * Separate on purpose, twice over. The buyer journeys above run in any app
48
+ * that mounts the checkout; these run in the app that operates the PLATFORM
49
+ * (typically a super-admin SPA), and most checkout consumers have none.
50
+ * Folding them into `paymentsFeatures` would hand every existing host
51
+ * scenarios whose steps it never registered — bddgen fails on the undefined
52
+ * steps — and folding the steps into `paymentsSteps` would hand it orphan
53
+ * definitions instead, which is what a strict bdd gate fails on. A host that
54
+ * wants these lists all three, next to `definePaymentsPlatformWorld`:
55
+ *
56
+ * ```ts
57
+ * defineBddConfig({
58
+ * features: [paymentsPlatformFeatures],
59
+ * featuresRoot: paymentsPlatformFeaturesRoot,
60
+ * steps: [paymentsPlatformSteps, 'tests/e2e/steps/**\/*.ts'],
61
+ * });
62
+ * ```
63
+ */
64
+ export declare const paymentsPlatformFeatures: string;
65
+ /** Same trap as {@link paymentsFeaturesRoot} — unset, the specs land under a path Playwright ignores. */
66
+ export declare const paymentsPlatformFeaturesRoot: string;
67
+ /** Compiled for Node, like {@link paymentsSteps} and for the same reason. */
68
+ export declare const paymentsPlatformSteps: string;
43
69
  //# sourceMappingURL=globs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"globs.d.ts","sourceRoot":"","sources":["../src/globs.ts"],"names":[],"mappings":"AA8BA,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,EAAE,MAAqD,CAAC;AAErF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAwC,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,aAAa,EAAE,MAAkD,CAAC"}
1
+ {"version":3,"file":"globs.d.ts","sourceRoot":"","sources":["../src/globs.ts"],"names":[],"mappings":"AA8BA,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,EAAE,MAAqD,CAAC;AAErF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAAwC,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,aAAa,EAAE,MAAkD,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,wBAAwB,EAAE,MAGtC,CAAC;AAEF,yGAAyG;AACzG,eAAO,MAAM,4BAA4B,EAAE,MAAiD,CAAC;AAE7F,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,EAAE,MAA2D,CAAC"}
package/dist/globs.js CHANGED
@@ -67,4 +67,30 @@ export const paymentsFeaturesRoot = join(packageRoot(), 'features');
67
67
  * in every worker.
68
68
  */
69
69
  export const paymentsSteps = join(packageRoot(), 'dist/steps/**/*.js');
70
+ /**
71
+ * The PLATFORM-OPERATIONS journeys (FUT-479 / FUT-483, packaged by FUT-573),
72
+ * as a SEPARATE opt-in glob triple.
73
+ *
74
+ * Separate on purpose, twice over. The buyer journeys above run in any app
75
+ * that mounts the checkout; these run in the app that operates the PLATFORM
76
+ * (typically a super-admin SPA), and most checkout consumers have none.
77
+ * Folding them into `paymentsFeatures` would hand every existing host
78
+ * scenarios whose steps it never registered — bddgen fails on the undefined
79
+ * steps — and folding the steps into `paymentsSteps` would hand it orphan
80
+ * definitions instead, which is what a strict bdd gate fails on. A host that
81
+ * wants these lists all three, next to `definePaymentsPlatformWorld`:
82
+ *
83
+ * ```ts
84
+ * defineBddConfig({
85
+ * features: [paymentsPlatformFeatures],
86
+ * featuresRoot: paymentsPlatformFeaturesRoot,
87
+ * steps: [paymentsPlatformSteps, 'tests/e2e/steps/**\/*.ts'],
88
+ * });
89
+ * ```
90
+ */
91
+ export const paymentsPlatformFeatures = join(packageRoot(), 'features-platform/**/*.feature');
92
+ /** Same trap as {@link paymentsFeaturesRoot} — unset, the specs land under a path Playwright ignores. */
93
+ export const paymentsPlatformFeaturesRoot = join(packageRoot(), 'features-platform');
94
+ /** Compiled for Node, like {@link paymentsSteps} and for the same reason. */
95
+ export const paymentsPlatformSteps = join(packageRoot(), 'dist/steps-platform/**/*.js');
70
96
  //# sourceMappingURL=globs.js.map
package/dist/globs.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"globs.js","sourceRoot":"","sources":["../src/globs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C;;;;;;;;;;;;;;GAcG;AACH,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEhD;;;;;GAKG;AACH,SAAS,WAAW;IAClB,OAAO,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,MAAM,gBAAgB,GAAW,IAAI,CAAC,WAAW,EAAE,EAAE,uBAAuB,CAAC,CAAC;AAErF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAW,IAAI,CAAC,WAAW,EAAE,EAAE,UAAU,CAAC,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAW,IAAI,CAAC,WAAW,EAAE,EAAE,oBAAoB,CAAC,CAAC"}
1
+ {"version":3,"file":"globs.js","sourceRoot":"","sources":["../src/globs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C;;;;;;;;;;;;;;GAcG;AACH,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEhD;;;;;GAKG;AACH,SAAS,WAAW;IAClB,OAAO,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,CAAC;AACzE,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,MAAM,gBAAgB,GAAW,IAAI,CAAC,WAAW,EAAE,EAAE,uBAAuB,CAAC,CAAC;AAErF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAW,IAAI,CAAC,WAAW,EAAE,EAAE,UAAU,CAAC,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAW,IAAI,CAAC,WAAW,EAAE,EAAE,oBAAoB,CAAC,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAW,IAAI,CAClD,WAAW,EAAE,EACb,gCAAgC,CACjC,CAAC;AAEF,yGAAyG;AACzG,MAAM,CAAC,MAAM,4BAA4B,GAAW,IAAI,CAAC,WAAW,EAAE,EAAE,mBAAmB,CAAC,CAAC;AAE7F,6EAA6E;AAC7E,MAAM,CAAC,MAAM,qBAAqB,GAAW,IAAI,CAAC,WAAW,EAAE,EAAE,6BAA6B,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -33,6 +33,15 @@
33
33
  */
34
34
  export { definePaymentsWorld, paymentsWorld, type PaymentsFixtures, type PaymentsStore, type PaymentsWireProbe, type PaymentsWorld, } from './world.js';
35
35
  export { paymentsFeatures, paymentsFeaturesRoot, paymentsSteps } from './globs.js';
36
+ /**
37
+ * The PLATFORM-OPERATIONS journeys (FUT-479 / FUT-483, packaged by FUT-573):
38
+ * the Connect-application consult and the platform homologação, for the app
39
+ * that operates the platform. A separate OPT-IN port and glob triple — see
40
+ * `platform-world.ts` for why folding them into `PaymentsWorld` would have
41
+ * broken every checkout-only consumer.
42
+ */
43
+ export { definePaymentsPlatformWorld, paymentsPlatformWorld, type ConnectApplicationShape, type PaymentsPlatformWorld, type PlatformHomologacaoShape, } from './platform-world.js';
44
+ export { paymentsPlatformFeatures, paymentsPlatformFeaturesRoot, paymentsPlatformSteps, } from './globs.js';
36
45
  /**
37
46
  * The buyer gestures the packaged steps are built from, exported so a host can
38
47
  * write its OWN specs in the same vocabulary. Every one drives a test id the
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEnF;;;;GAIG;AACH,OAAO,EACL,UAAU,EACV,WAAW,EACX,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,SAAS,GACV,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEnF;;;;;;GAMG;AACH,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,GAC9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,OAAO,EACL,UAAU,EACV,WAAW,EACX,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,SAAS,GACV,MAAM,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -33,6 +33,15 @@
33
33
  */
34
34
  export { definePaymentsWorld, paymentsWorld, } from './world.js';
35
35
  export { paymentsFeatures, paymentsFeaturesRoot, paymentsSteps } from './globs.js';
36
+ /**
37
+ * The PLATFORM-OPERATIONS journeys (FUT-479 / FUT-483, packaged by FUT-573):
38
+ * the Connect-application consult and the platform homologação, for the app
39
+ * that operates the platform. A separate OPT-IN port and glob triple — see
40
+ * `platform-world.ts` for why folding them into `PaymentsWorld` would have
41
+ * broken every checkout-only consumer.
42
+ */
43
+ export { definePaymentsPlatformWorld, paymentsPlatformWorld, } from './platform-world.js';
44
+ export { paymentsPlatformFeatures, paymentsPlatformFeaturesRoot, paymentsPlatformSteps, } from './globs.js';
36
45
  /**
37
46
  * The buyer gestures the packaged steps are built from, exported so a host can
38
47
  * write its OWN specs in the same vocabulary. Every one drives a test id the
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EACL,mBAAmB,EACnB,aAAa,GAKd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEnF;;;;GAIG;AACH,OAAO,EACL,UAAU,EACV,WAAW,EACX,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,SAAS,GACV,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EACL,mBAAmB,EACnB,aAAa,GAKd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEnF;;;;;;GAMG;AACH,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,GAItB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,OAAO,EACL,UAAU,EACV,WAAW,EACX,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,SAAS,GACV,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,78 @@
1
+ import type { Page } from '@playwright/test';
2
+ /**
3
+ * The port a HOST implements to run the packaged PLATFORM-OPERATIONS journeys
4
+ * (FUT-479 / FUT-483, packaged by FUT-573) — the Connect-application consult
5
+ * screen and the platform homologação.
6
+ *
7
+ * A SEPARATE port from {@link import('./world.js').PaymentsWorld}, on purpose.
8
+ * The buyer journeys are for any app that mounts the checkout; these are for
9
+ * the app that operates the PLATFORM (typically a super-admin SPA), and most
10
+ * consumers of the checkout have no such surface. Folding these into
11
+ * `PaymentsWorld` would have broken every existing host on the next version
12
+ * bump; a second opt-in port breaks nobody. The features live under their own
13
+ * globs (`paymentsPlatformFeatures` / `paymentsPlatformSteps`) for the same
14
+ * reason — a host that never lists them never compiles them.
15
+ *
16
+ * Every assertion in the journeys reads a test id the payments package's own
17
+ * platform components render (`connect-env-SANDBOX`, `homologacao-status-chip`,
18
+ * …), so they hold in any app that mounts `ConnectApplicationPanel` /
19
+ * `PlatformHomologacao` from `@12-apps/payments-frontend`.
20
+ */
21
+ /**
22
+ * The SHAPE of the deployment a Connect-application scenario is set in.
23
+ *
24
+ * `unconfigured` — no OAuth application credentials for either environment,
25
+ * which is what a fresh e2e stack honestly is. The consult then renders both
26
+ * cards in their "nenhuma aplicação configurada" state with no network call —
27
+ * the screen's baseline value, reachable without stubbing PagBank.
28
+ *
29
+ * Adding a member is a breaking change for hosts, deliberately — same
30
+ * argument as `PaymentsStore`: a shape nobody can build is a scenario that
31
+ * silently never runs.
32
+ */
33
+ export type ConnectApplicationShape = 'unconfigured';
34
+ /**
35
+ * The SHAPE of the platform a homologação scenario is set in.
36
+ *
37
+ * `unrequested` — no outcome recorded for the provider AND no platform
38
+ * SANDBOX token stored, which again is what a fresh e2e stack is: the screen
39
+ * shows the honest "não solicitada", the outcome form performs the first real
40
+ * write, and the anexo generator refuses with its reason instead of calling
41
+ * the provider.
42
+ *
43
+ * PRODUCING the shape is the host's job, not just navigating to the screen:
44
+ * one scenario records an outcome, so a later `unrequested` opening must
45
+ * clear it again (the same way `PaymentsWorld.open` seeds a store).
46
+ */
47
+ export type PlatformHomologacaoShape = 'unrequested';
48
+ /** Everything a host supplies to run the packaged platform journeys. */
49
+ export interface PaymentsPlatformWorld {
50
+ /**
51
+ * Put a signed-in PLATFORM OPERATOR on the Connect-application screen of a
52
+ * deployment of this shape. Auth is the host's own business — these
53
+ * journeys never see a login form.
54
+ */
55
+ openConnectApplication(page: Page, shape: ConnectApplicationShape): Promise<void>;
56
+ /**
57
+ * Put a signed-in platform operator on the homologação screen of a platform
58
+ * of this shape. The host must wire the screen so a recorded outcome
59
+ * refreshes the `record` the component renders — the journey asserts the
60
+ * status chip flips without a reload.
61
+ */
62
+ openHomologacao(page: Page, shape: PlatformHomologacaoShape): Promise<void>;
63
+ }
64
+ /**
65
+ * Install the host's implementation. Call this from a module inside the
66
+ * host's OWN steps glob — playwright-bdd imports every step file before any
67
+ * scenario runs, so a top-level call there is registered in time, in every
68
+ * worker. Independent of `definePaymentsWorld`: a host may implement either
69
+ * port, or both.
70
+ */
71
+ export declare function definePaymentsPlatformWorld(world: PaymentsPlatformWorld): void;
72
+ /**
73
+ * The installed world. Throws rather than degrading, for the same reason as
74
+ * `paymentsWorld()`: a journey against a half-configured world fails deep
75
+ * inside a step, several layers from the actual cause.
76
+ */
77
+ export declare function paymentsPlatformWorld(): PaymentsPlatformWorld;
78
+ //# sourceMappingURL=platform-world.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-world.d.ts","sourceRoot":"","sources":["../src/platform-world.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,uBAAuB,GAAG,cAAc,CAAC;AAErD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,wBAAwB,GAAG,aAAa,CAAC;AAErD,wEAAwE;AACxE,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,sBAAsB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF;;;;;OAKG;IACH,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7E;AAID;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI,CAE9E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,qBAAqB,CAQ7D"}
@@ -0,0 +1,24 @@
1
+ let installed = null;
2
+ /**
3
+ * Install the host's implementation. Call this from a module inside the
4
+ * host's OWN steps glob — playwright-bdd imports every step file before any
5
+ * scenario runs, so a top-level call there is registered in time, in every
6
+ * worker. Independent of `definePaymentsWorld`: a host may implement either
7
+ * port, or both.
8
+ */
9
+ export function definePaymentsPlatformWorld(world) {
10
+ installed = world;
11
+ }
12
+ /**
13
+ * The installed world. Throws rather than degrading, for the same reason as
14
+ * `paymentsWorld()`: a journey against a half-configured world fails deep
15
+ * inside a step, several layers from the actual cause.
16
+ */
17
+ export function paymentsPlatformWorld() {
18
+ if (!installed) {
19
+ throw new Error('No PaymentsPlatformWorld installed. Call definePaymentsPlatformWorld(...) from a ' +
20
+ "module inside this app's bdd `steps` glob — see @12-apps/payments-e2e's README.");
21
+ }
22
+ return installed;
23
+ }
24
+ //# sourceMappingURL=platform-world.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-world.js","sourceRoot":"","sources":["../src/platform-world.ts"],"names":[],"mappings":"AAoEA,IAAI,SAAS,GAAiC,IAAI,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAA4B;IACtE,SAAS,GAAG,KAAK,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IACnC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,mFAAmF;YACjF,iFAAiF,CACpF,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=activation.steps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activation.steps.d.ts","sourceRoot":"","sources":["../../src/steps/activation.steps.ts"],"names":[],"mappings":""}
@@ -0,0 +1,74 @@
1
+ import { expect } from '@playwright/test';
2
+ import { DECLINE_PAN, fillCard, fillCpf } from '../helpers/checkout.js';
3
+ import { paymentsWorld } from '../world.js';
4
+ import { Given, Then, When } from './fixtures.js';
5
+ /**
6
+ * ACTIVATING A PROVIDER (FUT-463, made real for every SDK provider by
7
+ * FUT-689) — the merchant admin's side of the till.
8
+ *
9
+ * The package renders the switch and its lock (`payments-enabled-toggle`,
10
+ * `payments-enable-hint`, `payments-status`); the activation step itself is
11
+ * HOST-owned, rendered into the `renderVerification` slot. So these steps
12
+ * read two vocabularies:
13
+ *
14
+ * - the package's own test ids, which mean the same thing in any host;
15
+ * - the activation-step contract a host's slot must render — the shared
16
+ * card form (`card-number`…, `buyer-cpf`) plus `activation-pay`,
17
+ * `activation-result`, `activation-refunded`, `activation-error`, and the
18
+ * fixture probe pair `activation-enable-attempt` /
19
+ * `activation-enable-refusal` (a raw enable request and the refusal it
20
+ * gets, the same affordance the wire probe is).
21
+ *
22
+ * The card the owner types decides the outcome, exactly as in the wallet
23
+ * journey: the shared `DECLINE_PAN` is refused with a named reason, any other
24
+ * valid card pays the cent and gets it back.
25
+ */
26
+ /** The "Recebendo vendas" switch — MUI puts the state on the inner checkbox. */
27
+ function salesSwitch(page) {
28
+ return page.getByTestId('payments-enabled-toggle').getByRole('checkbox');
29
+ }
30
+ Given('the owner opens the settings of a connected but unproven provider', async ({ page }) => {
31
+ await paymentsWorld().open(page, 'activation');
32
+ });
33
+ Then('the sales switch is locked off until a real charge lands', async ({ page }) => {
34
+ await expect(salesSwitch(page)).toBeDisabled();
35
+ // The package's own lock hint — the quoted words are its pt-BR product copy.
36
+ await expect(page.getByTestId('payments-enable-hint')).toContainText('depois dos 3 passos');
37
+ });
38
+ When('the owner tries to force the provider on anyway', async ({ page }) => {
39
+ await page.getByTestId('activation-enable-attempt').click();
40
+ });
41
+ Then('the enable request is refused as unproven', async ({ page }) => {
42
+ // The package's own refusal, by name: the server said no, not the screen.
43
+ await expect(page.getByTestId('activation-enable-refusal')).toContainText('409');
44
+ await expect(page.getByTestId('activation-enable-refusal')).toContainText('UnprovenProviderError');
45
+ });
46
+ When('the owner pays the verification charge with their card', async ({ page }) => {
47
+ await fillCard(page);
48
+ await fillCpf(page);
49
+ await page.getByTestId('activation-pay').click();
50
+ });
51
+ When('the owner pays the verification charge with a refused card', async ({ page }) => {
52
+ await fillCard(page, DECLINE_PAN);
53
+ await fillCpf(page);
54
+ await page.getByTestId('activation-pay').click();
55
+ });
56
+ Then('the provider is proven and receiving sales', async ({ page }) => {
57
+ // VERIFICADO is reserved for a landed charge — the chip's one green word.
58
+ await expect(page.getByTestId('payments-status')).toHaveText('VERIFICADO');
59
+ await expect(salesSwitch(page)).toBeChecked();
60
+ });
61
+ Then('the screen says the cent came back', async ({ page }) => {
62
+ // The refund fact, in the screen's own pt-BR copy.
63
+ await expect(page.getByTestId('activation-refunded')).toContainText('estornado');
64
+ });
65
+ Then("the refusal names the provider's reason", async ({ page }) => {
66
+ await expect(page.getByTestId('activation-error')).toContainText('recusada');
67
+ await expect(page.getByTestId('activation-error')).toContainText('CARD_DECLINED');
68
+ });
69
+ Then('the provider received each attempt as its own charge', async ({ page }) => {
70
+ // Two charges REACHED the provider: a retry that replayed the first
71
+ // refusal would have left this at one.
72
+ await expect(paymentsWorld().wire.providerChargeCount(page)).toHaveText('2');
73
+ });
74
+ //# sourceMappingURL=activation.steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activation.steps.js","sourceRoot":"","sources":["../../src/steps/activation.steps.ts"],"names":[],"mappings":"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"}
@@ -18,15 +18,31 @@ import { Given, Then, When } from './fixtures.js';
18
18
  Given('a compradora abre o checkout de uma loja com Google Pay', async ({ page }) => {
19
19
  await paymentsWorld().open(page, 'google-pay');
20
20
  });
21
+ Given('a compradora abre o checkout de uma loja com Apple Pay', async ({ page }) => {
22
+ await paymentsWorld().open(page, 'apple-pay');
23
+ });
24
+ /** The SAME store shape, on a device without Apple Pay (any non-Safari). */
25
+ Given('a compradora abre o checkout da loja com Apple Pay num aparelho sem Apple Pay', async ({ page }) => {
26
+ await paymentsWorld().open(page, 'apple-pay-unsupported');
27
+ });
21
28
  When('ela paga com o Google Pay', async ({ page }) => {
22
29
  await page.getByTestId('google-pay-button').click();
23
30
  });
31
+ When('ela paga com o Apple Pay', async ({ page }) => {
32
+ await page.getByTestId('apple-pay-button').click();
33
+ });
24
34
  Then('ela vê o botão do Google Pay', async ({ page }) => {
25
35
  await expect(page.getByTestId('google-pay-button')).toBeVisible();
26
36
  });
27
37
  Then('nenhum botão do Google Pay é mostrado', async ({ page }) => {
28
38
  await expect(page.getByTestId('google-pay-button')).toHaveCount(0);
29
39
  });
40
+ Then('ela vê o botão do Apple Pay', async ({ page }) => {
41
+ await expect(page.getByTestId('apple-pay-button')).toBeVisible();
42
+ });
43
+ Then('nenhum botão do Apple Pay é mostrado', async ({ page }) => {
44
+ await expect(page.getByTestId('apple-pay-button')).toHaveCount(0);
45
+ });
30
46
  Then('a cobrança enviada ao provedor carrega a carteira do Google', async ({ page }) => {
31
47
  // What the PROVIDER received, not what the client recorded sending: hosts
32
48
  // tag a provider-charge line with `wallet:<TYPE>` when the charge's card
@@ -35,4 +51,7 @@ Then('a cobrança enviada ao provedor carrega a carteira do Google', async ({ pa
35
51
  // wallet body — the sheet then produced a token the charge never carried.
36
52
  await expect(paymentsWorld().wire.providerCharges(page)).toContainText('wallet:GOOGLE_PAY');
37
53
  });
54
+ Then('a cobrança enviada ao provedor carrega a carteira da Apple', async ({ page }) => {
55
+ await expect(paymentsWorld().wire.providerCharges(page)).toContainText('wallet:APPLE_PAY');
56
+ });
38
57
  //# sourceMappingURL=carteira.steps.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"carteira.steps.js","sourceRoot":"","sources":["../../src/steps/carteira.steps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAElD;;;;;;;;;;;;;GAaG;AAEH,KAAK,CAAC,yDAAyD,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IAClF,MAAM,aAAa,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2BAA2B,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IACnD,MAAM,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,KAAK,EAAE,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8BAA8B,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IACtD,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AACpE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uCAAuC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IAC/D,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6DAA6D,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IACrF,0EAA0E;IAC1E,yEAAyE;IACzE,wEAAwE;IACxE,0EAA0E;IAC1E,0EAA0E;IAC1E,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC;AAC9F,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"carteira.steps.js","sourceRoot":"","sources":["../../src/steps/carteira.steps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=saved-card-wallet.steps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saved-card-wallet.steps.d.ts","sourceRoot":"","sources":["../../src/steps/saved-card-wallet.steps.ts"],"names":[],"mappings":""}
@@ -0,0 +1,65 @@
1
+ import { expect } from '@playwright/test';
2
+ import { DECLINE_PAN, fillCard } from '../helpers/checkout.js';
3
+ import { paymentsWorld } from '../world.js';
4
+ import { Given, Then, When } from './fixtures.js';
5
+ /**
6
+ * SAVING A CARD WITHOUT BUYING (FUT-183, over FUT-478's buyer vault rows).
7
+ *
8
+ * A separate file from `carteira.steps.ts` on purpose: that one is the DIGITAL
9
+ * wallets (Google Pay / Apple Pay) — a faster way to pay inside checkout.
10
+ * These steps are the SAVED-CARD wallet: the package's manage-cards surface,
11
+ * reached outside any purchase, where nothing is charged at all.
12
+ *
13
+ * Every Then reads a test id the package's own vault screens render
14
+ * (`manage-cards*`, `add-card*`), plus the shared card form ids — so the
15
+ * journey means the same thing in any host that mounts `screens.ManageCards`.
16
+ * The card the buyer types decides the outcome: the shared `DECLINE_PAN` is
17
+ * the one the stub refuses at validation.
18
+ */
19
+ Given("the shopper opens the store's card wallet", async ({ page }) => {
20
+ await paymentsWorld().open(page, 'wallet');
21
+ });
22
+ When('she decides to add a card', async ({ page }) => {
23
+ await page.getByTestId('manage-cards-add').click();
24
+ // Wait for the FORM, not merely the click: `/cards/begin` runs in between,
25
+ // and typing into a form that has not mounted is the flake this avoids.
26
+ await expect(page.getByTestId('add-card')).toBeVisible();
27
+ });
28
+ When('she fills in the card and saves it', async ({ page }) => {
29
+ await fillCard(page);
30
+ await page.getByTestId('add-card-save').click();
31
+ });
32
+ When('she tries to save a refused card', async ({ page }) => {
33
+ await fillCard(page, DECLINE_PAN);
34
+ await page.getByTestId('add-card-save').click();
35
+ });
36
+ Then('the card is stored and appears in the list', async ({ page }) => {
37
+ await expect(page.getByTestId('add-card-saved')).toBeVisible();
38
+ await expect(page.getByTestId('manage-cards-list')).toBeVisible();
39
+ await expect(page.getByTestId('manage-cards-empty')).toHaveCount(0);
40
+ });
41
+ Then('the list shows only the brand and the last digits', async ({ page }) => {
42
+ // Display metadata ONLY. The vault token — the thing that can charge —
43
+ // never reaches this screen; what she reads back is brand + last4 + expiry.
44
+ // The quoted strings are the screen's pt-BR product copy, asserted as-is.
45
+ const list = page.getByTestId('manage-cards-list');
46
+ await expect(list).toContainText('••••');
47
+ await expect(list).toContainText('Validade');
48
+ });
49
+ Then('the refusal explains why and the form stays on screen', async ({ page }) => {
50
+ // The endpoint's own reason, and the form kept editable under it — wiping
51
+ // her input to say the card was refused would be the screen working
52
+ // against her. The asserted word is the pt-BR product copy of the reason.
53
+ await expect(page.getByTestId('add-card-error')).toBeVisible();
54
+ await expect(page.getByTestId('add-card-error')).toContainText('cartão');
55
+ await expect(page.getByTestId('card-number')).toBeVisible();
56
+ });
57
+ Then('the wallet still holds no card', async ({ page }) => {
58
+ await expect(page.getByTestId('manage-cards-empty')).toBeVisible();
59
+ await expect(page.getByTestId('manage-cards-list')).toHaveCount(0);
60
+ });
61
+ Then('the empty wallet invites saving the first card', async ({ page }) => {
62
+ await expect(page.getByTestId('manage-cards-empty')).toBeVisible();
63
+ await expect(page.getByTestId('manage-cards-add')).toBeVisible();
64
+ });
65
+ //# sourceMappingURL=saved-card-wallet.steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saved-card-wallet.steps.js","sourceRoot":"","sources":["../../src/steps/saved-card-wallet.steps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=plataforma.steps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plataforma.steps.d.ts","sourceRoot":"","sources":["../../src/steps-platform/plataforma.steps.ts"],"names":[],"mappings":""}
@@ -0,0 +1,78 @@
1
+ import { expect } from '@playwright/test';
2
+ import { paymentsPlatformWorld } from '../platform-world.js';
3
+ import { Given, Then, When } from '../steps/fixtures.js';
4
+ /**
5
+ * THE PLATFORM OPERATOR'S STEPS (FUT-479 / FUT-483, packaged by FUT-573).
6
+ *
7
+ * A separate file tree from `../steps/` on purpose: these register step
8
+ * definitions for the PLATFORM journeys, which a host opts into with the
9
+ * `paymentsPlatformSteps` glob. Compiling them into the buyer steps' glob
10
+ * would hand every checkout-only consumer a set of orphan definitions — and
11
+ * an orphan definition is exactly what a strict bdd gate fails on.
12
+ *
13
+ * Every Then reads a test id the payments package's own platform components
14
+ * render, so the assertions mean the same thing in any host that mounts
15
+ * `ConnectApplicationPanel` / `PlatformHomologacao`.
16
+ */
17
+ // ---------------------------------------------------------------------------
18
+ // The Connect application (FUT-479)
19
+ // ---------------------------------------------------------------------------
20
+ Given('a operadora abre a aplicação Connect de uma instalação sem aplicação registrada', async ({ page }) => {
21
+ await paymentsPlatformWorld().openConnectApplication(page, 'unconfigured');
22
+ });
23
+ Then('ela vê o callback desta instalação', async ({ page }) => {
24
+ const callback = page.getByTestId('connect-expected-redirect');
25
+ await expect(callback).toBeVisible();
26
+ // The exact URL is the host's own; what the journey pins is that SOMETHING
27
+ // is spelled out for the operator to compare against.
28
+ await expect(callback).not.toHaveText('');
29
+ });
30
+ Then('cada ambiente aparece em seu próprio cartão', async ({ page }) => {
31
+ await expect(page.getByTestId('connect-env-SANDBOX')).toBeVisible();
32
+ await expect(page.getByTestId('connect-env-PRODUCTION')).toBeVisible();
33
+ });
34
+ Then('os dois ambientes se declaram sem aplicação configurada', async ({ page }) => {
35
+ await expect(page.getByTestId('connect-env-SANDBOX')).toContainText('Nenhuma aplicação configurada neste ambiente.');
36
+ await expect(page.getByTestId('connect-env-PRODUCTION')).toContainText('Nenhuma aplicação configurada neste ambiente.');
37
+ });
38
+ // ---------------------------------------------------------------------------
39
+ // The homologação (FUT-483)
40
+ // ---------------------------------------------------------------------------
41
+ Given('a operadora abre a homologação de uma plataforma que nunca a solicitou', async ({ page }) => {
42
+ await paymentsPlatformWorld().openHomologacao(page, 'unrequested');
43
+ });
44
+ Then('a situação é {string}', async ({ page }, label) => {
45
+ await expect(page.getByTestId('homologacao-status-chip')).toHaveText(label);
46
+ });
47
+ Then('o formulário oficial está a um clique', async ({ page }) => {
48
+ const link = page.getByTestId('homologacao-form-link');
49
+ await expect(link).toBeVisible();
50
+ await expect(link).toHaveAttribute('href', /pipefy/);
51
+ });
52
+ Then('as respostas prontas nomeiam a API de Pedidos e a API Connect', async ({ page }) => {
53
+ const services = page.getByTestId('homologacao-services');
54
+ await expect(services).toContainText('API de Pedidos e Pagamentos (Order)');
55
+ await expect(services).toContainText('API Connect');
56
+ });
57
+ When('ela registra o protocolo da solicitação', async ({ page }) => {
58
+ await page.getByTestId('homologacao-protocol').fill('PIPE-journey-001');
59
+ await page.getByTestId('homologacao-save').click();
60
+ });
61
+ Then('o registro é confirmado', async ({ page }) => {
62
+ await expect(page.getByTestId('homologacao-save-ok')).toBeVisible();
63
+ });
64
+ /**
65
+ * The chip flipping WITHOUT a reload is the point: the host's save must
66
+ * refresh the `record` the component renders — the wiring the port's
67
+ * docstring demands.
68
+ */
69
+ Then('a situação passa a ser {string}', async ({ page }, label) => {
70
+ await expect(page.getByTestId('homologacao-status-chip')).toHaveText(label);
71
+ });
72
+ When('ela tenta gerar o anexo de evidências', async ({ page }) => {
73
+ await page.getByTestId('homologacao-anexo-button').click();
74
+ });
75
+ Then('ela vê o motivo pelo qual o anexo não saiu', async ({ page }) => {
76
+ await expect(page.getByTestId('homologacao-anexo-error')).not.toBeEmpty();
77
+ });
78
+ //# sourceMappingURL=plataforma.steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plataforma.steps.js","sourceRoot":"","sources":["../../src/steps-platform/plataforma.steps.ts"],"names":[],"mappings":"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"}
package/dist/world.d.ts CHANGED
@@ -63,6 +63,39 @@ export type PaymentsStore =
63
63
  * uses an installed global without touching the network).
64
64
  */
65
65
  | 'google-pay'
66
+ /**
67
+ * A store whose chain head declares Apple Pay (FUT-472), opened on a device
68
+ * that HAS it: the host provides a page where `window.ApplePaySession`
69
+ * exists and `canMakePayments()` answers true (a stub, outside Safari),
70
+ * plus a merchant-validation port that answers a session.
71
+ */
72
+ | 'apple-pay'
73
+ /**
74
+ * The SAME Apple Pay store on a device WITHOUT Apple Pay (every non-Safari
75
+ * browser): no `ApplePaySession` global. The scenario this hosts is the
76
+ * fallback rule — no button, and the card form stays the way to pay.
77
+ */
78
+ | 'apple-pay-unsupported'
79
+ /**
80
+ * The buyer's saved-card WALLET (FUT-183 over FUT-478), not a checkout: the
81
+ * host opens the package's manage-cards surface at a store whose provider
82
+ * can vault — one mintable chain entry with the vault seam, connected in
83
+ * stub mode — and the wallet starts EMPTY. The card the buyer types decides
84
+ * the outcome: the package's `DECLINE_PAN` is refused at validation, any
85
+ * other valid card is stored. (Not a digital wallet — those are the
86
+ * `google-pay` / `apple-pay` shapes above.)
87
+ */
88
+ | 'wallet'
89
+ /**
90
+ * A merchant ADMIN surface, not a checkout (FUT-463/FUT-689): the settings
91
+ * screen of ONE provider that declares the activation charge, connected in
92
+ * stub mode and never charged — so the sales switch starts locked off. The
93
+ * host lands the owner on that provider's own panel, whose host-rendered
94
+ * activation step shows the shared card form (`card-number`…, `buyer-cpf`)
95
+ * plus the `activation-*` test ids the steps file documents. The card the
96
+ * owner types decides the outcome, exactly as in the `wallet` shape.
97
+ */
98
+ | 'activation'
66
99
  /** Declares the on-page screen (FUT-596). */
67
100
  | 'screen-on-page'
68
101
  /** Declares the hand-off screen (FUT-596). */
@@ -1 +1 @@
1
- {"version":3,"file":"world.d.ts","sourceRoot":"","sources":["../src/world.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"world.d.ts","sourceRoot":"","sources":["../src/world.ts"],"names":[],"mappings":"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"}
package/dist/world.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"world.js","sourceRoot":"","sources":["../src/world.ts"],"names":[],"mappings":"AAyIA,IAAI,SAAS,GAAyB,IAAI,CAAC;AAE3C;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAoB;IACtD,SAAS,GAAG,KAAK,CAAC;AACpB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa;IAC3B,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,0EAA0E;YACxE,0EAA0E,CAC7E,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"world.js","sourceRoot":"","sources":["../src/world.ts"],"names":[],"mappings":"AA0KA,IAAI,SAAS,GAAyB,IAAI,CAAC;AAE3C;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAoB;IACtD,SAAS,GAAG,KAAK,CAAC;AACpB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa;IAC3B,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,0EAA0E;YACxE,0EAA0E,CAC7E,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,29 @@
1
+ @journey @activation
2
+ Feature: Activating a provider
3
+
4
+ "Connected" and "can charge" are different facts, and the gap between them
5
+ is where a store ships broken: credentials authenticate, the switch flips,
6
+ and the first real shopper is refused. So a provider that declares the
7
+ activation charge EARNS its switch — one cent through the owner's own card,
8
+ on the same rails a shopper's money takes, refunded on the spot — and stays
9
+ off until that cent has landed.
10
+
11
+ Background:
12
+ Given the owner opens the settings of a connected but unproven provider
13
+
14
+ Scenario: Enabling without proof is refused
15
+ Then the sales switch is locked off until a real charge lands
16
+ When the owner tries to force the provider on anyway
17
+ Then the enable request is refused as unproven
18
+
19
+ Scenario: Paying the one-cent verification enables the provider
20
+ When the owner pays the verification charge with their card
21
+ Then the provider is proven and receiving sales
22
+ And the screen says the cent came back
23
+
24
+ Scenario: A refused card names the reason and a retry is a fresh charge
25
+ When the owner pays the verification charge with a refused card
26
+ Then the refusal names the provider's reason
27
+ When the owner pays the verification charge with their card
28
+ Then the provider is proven and receiving sales
29
+ And the provider received each attempt as its own charge
@@ -0,0 +1,25 @@
1
+ @journey @apple-pay
2
+ Feature: Comprando com Apple Pay
3
+
4
+ O provedor processa Apple Pay só para Visa e Mastercard, então a folha da
5
+ Apple oferece só essas bandeiras — um cartão que seria recusado nunca chega
6
+ a ser oferecido. E a carteira é um atalho, nunca o único caminho: num
7
+ aparelho sem Apple Pay o botão simplesmente não existe e o formulário de
8
+ cartão continua fazendo a venda.
9
+
10
+ Scenario: A compra inteira acontece pela carteira
11
+ Given a compradora abre o checkout de uma loja com Apple Pay
12
+ When ela informa o CPF e segue para o pagamento
13
+ Then ela vê o botão do Apple Pay
14
+ And ela vê o formulário de cartão
15
+ When ela paga com o Apple Pay
16
+ Then o pagamento é confirmado
17
+ And a cobrança enviada ao provedor carrega a carteira da Apple
18
+
19
+ Scenario: Sem Apple Pay no aparelho, o cartão continua fazendo a venda
20
+ Given a compradora abre o checkout da loja com Apple Pay num aparelho sem Apple Pay
21
+ When ela informa o CPF e segue para o pagamento
22
+ Then nenhum botão do Apple Pay é mostrado
23
+ And ela vê o formulário de cartão
24
+ When ela paga com um cartão novo
25
+ Then o pagamento é confirmado
@@ -0,0 +1,29 @@
1
+ @journey @saved-cards
2
+ Feature: Saving a card without buying
3
+
4
+ Saving a card is not buying: no order exists, nothing is charged, and the
5
+ card still travels its usual path — the browser mints the token and the
6
+ provider validates it. What the shopper reads back is only what is fit to
7
+ show: the brand and the last digits. The token that can charge stays on the
8
+ store's side and never reaches this screen.
9
+
10
+ There is deliberately no delete button here: taking a card off the list is
11
+ between the store and the provider, not a tap on this screen.
12
+
13
+ Background:
14
+ Given the shopper opens the store's card wallet
15
+
16
+ Scenario: Saving a card without buying anything
17
+ When she decides to add a card
18
+ And she fills in the card and saves it
19
+ Then the card is stored and appears in the list
20
+ And the list shows only the brand and the last digits
21
+
22
+ Scenario: A card refused at validation explains why and stays off the list
23
+ When she decides to add a card
24
+ And she tries to save a refused card
25
+ Then the refusal explains why and the form stays on screen
26
+ And the wallet still holds no card
27
+
28
+ Scenario: The empty wallet invites saving the first card
29
+ Then the empty wallet invites saving the first card
@@ -0,0 +1,23 @@
1
+ @journey @plataforma
2
+ Feature: A aplicação que as lojas autorizam
3
+
4
+ A aplicação OAuth da plataforma — o que cada loja autoriza ao conectar a
5
+ própria conta PagBank — foi registrada à mão, e por muito tempo nada no
6
+ produto sabia dizer o que estava registrado, em qual ambiente, nem com qual
7
+ redirect_uri. O PagBank compara a redirect_uri byte a byte na troca do
8
+ token, então um cadastro diferente do callback desta instalação é uma falha
9
+ de OAuth silenciosa — e diagnosticar isso uma vez já custou tempo de gente.
10
+
11
+ Esta tela é a consulta feita permanente. Sandbox e produção são aplicações
12
+ SEPARADAS, com credenciais separadas, então cada ambiente responde por si; e
13
+ a tela existe justamente para os momentos em que algo está quebrado, então
14
+ uma instalação sem nada configurado também precisa se explicar.
15
+
16
+ Scenario: O callback que precisa estar registrado aparece por inteiro
17
+ Given a operadora abre a aplicação Connect de uma instalação sem aplicação registrada
18
+ Then ela vê o callback desta instalação
19
+ And cada ambiente aparece em seu próprio cartão
20
+
21
+ Scenario: Um ambiente sem aplicação diz isso com todas as letras
22
+ Given a operadora abre a aplicação Connect de uma instalação sem aplicação registrada
23
+ Then os dois ambientes se declaram sem aplicação configurada
@@ -0,0 +1,31 @@
1
+ @journey @plataforma
2
+ Feature: A homologação é da plataforma
3
+
4
+ Somos o integrador direto: a homologação do PagBank é da PLATAFORMA, uma
5
+ única vez — as lojas são usuárias da plataforma e estão isentas. Sem ela,
6
+ cobranças em produção respondem 403 ACCESS_DENIED mesmo com credenciais
7
+ válidas, então "a plataforma está homologada?" é uma pergunta que vale
8
+ dinheiro e não pode depender da memória de alguém.
9
+
10
+ A tela carrega as três metades: a situação registrada (a AUSÊNCIA do
11
+ registro é o quarto estado honesto, "não solicitada" — exibido, nunca
12
+ oferecido), as respostas prontas do formulário oficial, e o gerador do
13
+ anexo de evidências, que roda com as credenciais de sandbox da própria
14
+ plataforma e recusa com o motivo quando não pode rodar.
15
+
16
+ Scenario: As respostas prontas nomeiam os dois serviços integrados
17
+ Given a operadora abre a homologação de uma plataforma que nunca a solicitou
18
+ Then a situação é "Não solicitada"
19
+ And o formulário oficial está a um clique
20
+ And as respostas prontas nomeiam a API de Pedidos e a API Connect
21
+
22
+ Scenario: Registrar a solicitação muda a situação sem recarregar
23
+ Given a operadora abre a homologação de uma plataforma que nunca a solicitou
24
+ When ela registra o protocolo da solicitação
25
+ Then o registro é confirmado
26
+ And a situação passa a ser "Solicitada"
27
+
28
+ Scenario: Sem token de sandbox, o anexo recusa com o motivo
29
+ Given a operadora abre a homologação de uma plataforma que nunca a solicitou
30
+ When ela tenta gerar o anexo de evidências
31
+ Then ela vê o motivo pelo qual o anexo não saiu
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@12-apps/payments-e2e",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "description": "The payments buyer journeys, as Gherkin a host runs against its own app",
6
6
  "repository": {
@@ -11,6 +11,7 @@
11
11
  "files": [
12
12
  "dist",
13
13
  "features",
14
+ "features-platform",
14
15
  "*.md"
15
16
  ],
16
17
  "exports": {
@@ -32,8 +33,8 @@
32
33
  "playwright-bdd": ">=8.0.0"
33
34
  },
34
35
  "devDependencies": {
35
- "@12-apps/eslint-config": "^1.19.0",
36
- "@12-apps/typescript-config": "^1.19.0",
36
+ "@12-apps/eslint-config": "^1.20.0",
37
+ "@12-apps/typescript-config": "^1.20.0",
37
38
  "@playwright/test": "^1.56.1",
38
39
  "playwright-bdd": "^8.4.1",
39
40
  "typescript": "5.9.2"