@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.
- package/README.md +67 -4
- package/dist/globs.d.ts +26 -0
- package/dist/globs.d.ts.map +1 -1
- package/dist/globs.js +26 -0
- package/dist/globs.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/platform-world.d.ts +78 -0
- package/dist/platform-world.d.ts.map +1 -0
- package/dist/platform-world.js +24 -0
- package/dist/platform-world.js.map +1 -0
- package/dist/steps/activation.steps.d.ts +2 -0
- package/dist/steps/activation.steps.d.ts.map +1 -0
- package/dist/steps/activation.steps.js +74 -0
- package/dist/steps/activation.steps.js.map +1 -0
- package/dist/steps/carteira.steps.js +19 -0
- package/dist/steps/carteira.steps.js.map +1 -1
- package/dist/steps/saved-card-wallet.steps.d.ts +2 -0
- package/dist/steps/saved-card-wallet.steps.d.ts.map +1 -0
- package/dist/steps/saved-card-wallet.steps.js +65 -0
- package/dist/steps/saved-card-wallet.steps.js.map +1 -0
- package/dist/steps-platform/plataforma.steps.d.ts +2 -0
- package/dist/steps-platform/plataforma.steps.d.ts.map +1 -0
- package/dist/steps-platform/plataforma.steps.js +78 -0
- package/dist/steps-platform/plataforma.steps.js.map +1 -0
- package/dist/world.d.ts +33 -0
- package/dist/world.d.ts.map +1 -1
- package/dist/world.js.map +1 -1
- package/features/activating-a-provider.feature +29 -0
- package/features/comprando-com-apple-pay.feature +25 -0
- package/features/saving-a-card.feature +29 -0
- package/features-platform/a-aplicacao-que-as-lojas-autorizam.feature +23 -0
- package/features-platform/a-homologacao-e-da-plataforma.feature +31 -0
- 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
|
|
8
|
-
hand-off and return, provider failover, issuer
|
|
9
|
-
store that cannot charge at all,
|
|
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` · `
|
|
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
|
package/dist/globs.d.ts.map
CHANGED
|
@@ -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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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 @@
|
|
|
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":"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,KAAK,CAAC,wDAAwD,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IACjF,MAAM,aAAa,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,4EAA4E;AAC5E,KAAK,CACH,+EAA+E,EAC/E,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IACjB,MAAM,aAAa,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;AAC5D,CAAC,CACF,CAAC;AAEF,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,0BAA0B,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IAClD,MAAM,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,KAAK,EAAE,CAAC;AACrD,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,6BAA6B,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IACrD,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AACnE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sCAAsC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IAC9D,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACpE,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;AAEH,IAAI,CAAC,4DAA4D,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IACpF,MAAM,MAAM,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;AAC7F,CAAC,CAAC,CAAC"}
|
|
@@ -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 @@
|
|
|
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). */
|
package/dist/world.d.ts.map
CHANGED
|
@@ -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":"
|
|
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
|
+
"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.
|
|
36
|
-
"@12-apps/typescript-config": "^1.
|
|
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"
|