使用 Javascript 填写 iframe 中的输入字段
fill out input field in iframe with Javascript
我使用 Stripe 进行支付,angular e2e 进行测试。我想将卡测试数据添加到付款中 window。 Stripe 注入一个 iframe incl。将表单元素放入#card-element(这是我的标记的一部分),但没有表单名称和 ID。这是 Stripe 注入支付容器后标记的一部分:
<div id="card-element" class="StripeElement StripeElement--empty">
<div class="__PrivateStripeElement">
<iframe frameborder="0" allowtransparency="true" scrolling="no" name="__privateStripeFrame5395" allowpaymentrequest="true" src="https://js.stripe.com/v3/elements-inner-card-xxx.html" ></iframe>
</div>
</div>
iframe 内部是(仍然只显示部分标记):
<form class="ElementsApp is-empty" dir="ltr">
<div tabindex="-1" class="CardNumberField CardNumberField--ltr">
<div class="CardNumberField-input-wrapper">
<input class="InputElement is-empty Input Input--empty" autocomplete="cc-number" autocorrect="off" spellcheck="false" type="text" name="cardnumber" data-elements-stable-field-name="cardNumber" inputmode="numeric" aria-label="Kredit- eller debetkortnummer" placeholder="Kortnummer" aria-invalid="false" value="">
</div>
</div>
<button tabindex="-1" aria-hidden="true" type="submit"></button>
</form>
// 完整 select 或来自检查员:
//#root > form > div > div.CardField-input-wrapper.is-ready-to-slide > span.CardField-number.CardField-child > span:nth-child(2) > div > div.CardNumberField-input-wrapper > span > input
我已经成功 select 卡片元素和 iframe:
var cont = document.getElementById('card-element');
console.log(cont); // i get the card-element markup
var iframe = cont.getElementsByTagName('iframe');
console.log(iframe);
iframe 在控制台中显示:
HTMLCollection []
0: iframe
length: 1
__privateStripeFrame3085: iframe
__proto__: HTMLCollection
从这里我有点卡住了,我在 iframe[0] 数组中四处点击,但我在列表中找不到 name="cardnumber",搜索它给了我 15 个匹配项,但是数据集未打开,所以仍然卡住。 CardNumberField-input-wrapper 只给出了 3 个命中,但同样的问题,没有打开...
所以我的问题是,如何将数据填充到名为“cardnumber”的输入字段中?
顺便说一句:我也知道跨域问题,但我还没有解决这些问题,并且不确定我是否会这样做,因为 iframe 是从 Stripe 注入的。
简短的回答是你不能,设计使然。出于安全原因,JavaScript 无法访问跨域 iframe 的内容。 Stripe 使用它来确保没有人可以访问 iframe 中包含的敏感信息(例如信用卡号)。
这有双重目的,既可以保护您的用户,又可以将您的 PCI 合规级别保持在最低水平。
如果您尝试自动化端到端测试,这确实会让事情变得棘手。幸运的是,有 Cypress that can get around that. Here's a good article on how to test Stripe Elements with Cypress: https://medium.com/@michabahr/testing-stripe-elements-with-cypress-5a2fc17ab27b
这样的工具
从安装到成功测试,我在不到 3 小时内基于这篇文章针对 Stripes iframe 卡元素解决方案使用 Cypress 制作了一个工作测试用例:https://medium.com/@michabahr/testing-stripe-elements-with-cypress-5a2fc17ab27b I had to make some modifications, these are mentioned here:
最初的想法 post 是使用 vanillaJS 实现同样的效果,所以你不能说它真的已经解决了。但我想说的是,与 Cypress 相比,我确实花了更长的时间来寻找 vanillaJS 的解决方案,后者易于使用,所以如果你处于同样的情况,请试一试 :-)
我使用 Stripe 进行支付,angular e2e 进行测试。我想将卡测试数据添加到付款中 window。 Stripe 注入一个 iframe incl。将表单元素放入#card-element(这是我的标记的一部分),但没有表单名称和 ID。这是 Stripe 注入支付容器后标记的一部分:
<div id="card-element" class="StripeElement StripeElement--empty">
<div class="__PrivateStripeElement">
<iframe frameborder="0" allowtransparency="true" scrolling="no" name="__privateStripeFrame5395" allowpaymentrequest="true" src="https://js.stripe.com/v3/elements-inner-card-xxx.html" ></iframe>
</div>
</div>
iframe 内部是(仍然只显示部分标记):
<form class="ElementsApp is-empty" dir="ltr">
<div tabindex="-1" class="CardNumberField CardNumberField--ltr">
<div class="CardNumberField-input-wrapper">
<input class="InputElement is-empty Input Input--empty" autocomplete="cc-number" autocorrect="off" spellcheck="false" type="text" name="cardnumber" data-elements-stable-field-name="cardNumber" inputmode="numeric" aria-label="Kredit- eller debetkortnummer" placeholder="Kortnummer" aria-invalid="false" value="">
</div>
</div>
<button tabindex="-1" aria-hidden="true" type="submit"></button>
</form>
// 完整 select 或来自检查员: //#root > form > div > div.CardField-input-wrapper.is-ready-to-slide > span.CardField-number.CardField-child > span:nth-child(2) > div > div.CardNumberField-input-wrapper > span > input
我已经成功 select 卡片元素和 iframe:
var cont = document.getElementById('card-element');
console.log(cont); // i get the card-element markup
var iframe = cont.getElementsByTagName('iframe');
console.log(iframe);
iframe 在控制台中显示:
HTMLCollection []
0: iframe
length: 1
__privateStripeFrame3085: iframe
__proto__: HTMLCollection
从这里我有点卡住了,我在 iframe[0] 数组中四处点击,但我在列表中找不到 name="cardnumber",搜索它给了我 15 个匹配项,但是数据集未打开,所以仍然卡住。 CardNumberField-input-wrapper 只给出了 3 个命中,但同样的问题,没有打开...
所以我的问题是,如何将数据填充到名为“cardnumber”的输入字段中?
顺便说一句:我也知道跨域问题,但我还没有解决这些问题,并且不确定我是否会这样做,因为 iframe 是从 Stripe 注入的。
简短的回答是你不能,设计使然。出于安全原因,JavaScript 无法访问跨域 iframe 的内容。 Stripe 使用它来确保没有人可以访问 iframe 中包含的敏感信息(例如信用卡号)。
这有双重目的,既可以保护您的用户,又可以将您的 PCI 合规级别保持在最低水平。
如果您尝试自动化端到端测试,这确实会让事情变得棘手。幸运的是,有 Cypress that can get around that. Here's a good article on how to test Stripe Elements with Cypress: https://medium.com/@michabahr/testing-stripe-elements-with-cypress-5a2fc17ab27b
这样的工具从安装到成功测试,我在不到 3 小时内基于这篇文章针对 Stripes iframe 卡元素解决方案使用 Cypress 制作了一个工作测试用例:https://medium.com/@michabahr/testing-stripe-elements-with-cypress-5a2fc17ab27b I had to make some modifications, these are mentioned here:
最初的想法 post 是使用 vanillaJS 实现同样的效果,所以你不能说它真的已经解决了。但我想说的是,与 Cypress 相比,我确实花了更长的时间来寻找 vanillaJS 的解决方案,后者易于使用,所以如果你处于同样的情况,请试一试 :-)