Это может не сработать для вашего варианта использования, но если / когда это сработает, это самый простой обходной путь, который я нашел.

ался проверить бланк оформления заказа с помощью cypress.io

Если кому-то удалось заставить это работать, пожалуйста, дайте мне знать. Я нашел тему по этому вопросу здесьhttps://github.com/cypress-io/cypress/issues/136 и на основании этого я придумал:

   cy.get('iframe.stripe_checkout_app')
      .wait(10000)
      .then($iframe => {
        const iframe = $iframe.contents()
        const myInput0 = iframe.find('input:eq(0)')
        const myInput1 = iframe.find('input:eq(1)')
        const myInput2 = iframe.find('input:eq(2)')
        const myButton = iframe.find('button')

        cy
          .wrap(myInput0)
          .invoke('val', 4000056655665556)
          .trigger('change')
        cy
          .wrap(myInput1)
          .invoke('val', 112019)
          .trigger('change')

        cy
          .wrap(myInput2)
          .invoke('val', 424)
          .trigger('change')

        cy.wrap(myButton).click({ force: true })
      })

Но проблема в том, что полосовая форма все еще не регистрирует входные значения. Вот маленький гиф из того, что происходитhttp://www.giphy.com/gifs/xT0xeEZ8CmCTVMwOU8, По сути, форма не регистрирует триггер ввода изменений.

Кто-нибудь знает, как вводить данные в форму в iframe с помощью кипариса?

Ответы на вопрос(4)

Это ненепосредственно ответьте на ваш вопрос, но после нескольких дней попыток манипулирования элементами в iframe с помощью jQuery, повторной реализации множества вещей, которые Cypress уже сделал, я ударил себя и начал делать это:

Cypress.Commands.add('openiframe', () => {
    return cy.get("iframe[src^='/']").then(iframe => {
        cy.visit(Cypress.$(iframe).attr('src'), { timeout: Cypress.config("pageLoadTimeout") });
    });
});

Это позволило мне просто cy.openiframe (). Then (() => {}); и действуйте так, как если бы сайт, который я тестировал, не помещал кучу функциональности в iframe.

Недостатком является то, что вы должны закончить то, что вы делаетене в фрейме прежде чем делать что-либо в iframe, так что вы не можете слишком легко переходить назад и вперед.

Это может не сработать для вашего варианта использования, но если / когда это сработает, это самый простой обходной путь, который я нашел.

Рабочий процесс iframe все еще довольно неуклюжэта особенность реализовано). Сейчас вы можете попытаться форсировать каждое взаимодействие с DOM:

cy.visit("https://jsfiddle.net/1w9jpnxo/1/");
cy.get("iframe").then( $iframe => {

    const $doc = $iframe.contents();
    cy.wrap( $doc.find("#input") ).type( "test", { force: true });
    cy.wrap( $doc.find("#submit") ).click({ force: true });
});
 Josh Pittman16 нояб. 2017 г., 18:16
Спасибо. К сожалению, это не работает. Я попробовал это, и это все то же самое. На этот раз красная рамка только вокруг ввода номера карты, но я все еще не могу отправить форму. В случае, если кто-то еще знает, является ли это чем-то конкретным для реакции-нашивки-проверки, вот краткий рисунок того, что происходит, когда я форсирую типgiphy.com/gifs/l2QEaH7zmQooawT6g

из поста @ izaacdb вэта тема.

cy.wait(5000)
cy.get('.__PrivateStripeElement > iframe').then($element => {

  const $body = $element.contents().find('body')

  let stripe = cy.wrap($body)
  stripe.find('.Input .InputElement').eq(0).click().type('4242424242424242')
  stripe = cy.wrap($body)
  stripe.find('.Input .InputElement').eq(1).click().type('4242')
  stripe = cy.wrap($body)
  stripe.find('.Input .InputElement').eq(2).click().type('424')
})

Однако для того, чтобы вышеперечисленное сработало, вам нужно сделать следующее (скопировано / вставлено из поста @ nerdmax из той же ветки, что и выше):

Большое спасибо @Vedelopment @ Брайан-Манн!

Я протестировал с компонентом Reaction-Stripe-Checkout, и он работает.

Просто добавьте некоторые детали решения, чтобы сэкономить время другим.

chromeWebSecurity disable:

// cypress.json

{
  "chromeWebSecurity": false
}

--disable-site-isolation-trials:

Проверьте:https://docs.cypress.io/api/plugins/browser-launch-api.html# И № 1951

// /plugins/index.js

module.exports = (on, config) => {
  on("before:browser:launch", (browser = {}, args) => {
    if (browser.name === "chrome") {
      args.push("--disable-site-isolation-trials");
      return args;
    }
  });
};
 Michael25 нояб. 2018 г., 23:39
 Albert Olivé11 дек. 2018 г., 15:43
Я только сделал часть ChromeWebSecurity, и это сработало
 Tyler Bell13 февр. 2019 г., 03:17
это прекрасно работает Спасибо!

ни один из найденных ответов не сработал бы полностью. Я добавил свое решение в кипарисвопрос GitHub для iframes (там немного больше контекста), а также здесь, чтобы, надеюсь, сэкономить время другим.

Я украл функцию onIframeReady () изэтот ответ stackoverflow.

По сути, он проверяет, загрузился ли iframe, и загрузит ли iframe.$iframe.contents().find("body"); переключиться на содержание. Если он не загружен, он подключит тот же код вload событие, поэтому оно будет запущено, как только загрузится iframe.

Это написано как пользовательская команда, чтобы разрешить использование цепочки кипариса после перехода на iframe, поэтому поместите следующее в вашsupport/commands.js файл:

Cypress.Commands.add("iframe", { prevSubject: "element" }, $iframe => {
  Cypress.log({
    name: "iframe",
    consoleProps() {
      return {
        iframe: $iframe,
      };
    },
  });

  return new Cypress.Promise(resolve => {
    onIframeReady(
      $iframe,
      () => {
        resolve($iframe.contents().find("body"));
      },
      () => {
        $iframe.on("load", () => {
          resolve($iframe.contents().find("body"));
        });
      }
    );
  });
});

function onIframeReady($iframe, successFn, errorFn) {
  try {
    const iCon = $iframe.first()[0].contentWindow,
      bl = "about:blank",
      compl = "complete";
    const callCallback = () => {
      try {
        const $con = $iframe.contents();
        if ($con.length === 0) {
          // https://git.io/vV8yU
          throw new Error("iframe inaccessible");
        }
        successFn($con);
      } catch (e) {
        // accessing contents failed
        errorFn();
      }
    };

    const observeOnload = () => {
      $iframe.on("load.jqueryMark", () => {
        try {
          const src = $iframe.attr("src").trim(),
            href = iCon.location.href;
          if (href !== bl || src === bl || src === "") {
            $iframe.off("load.jqueryMark");
            callCallback();
          }
        } catch (e) {
          errorFn();
        }
      });
    };
    if (iCon.document.readyState === compl) {
      const src = $iframe.attr("src").trim(),
        href = iCon.location.href;
      if (href === bl && src !== bl && src !== "") {
        observeOnload();
      } else {
        callCallback();
      }
    } else {
      observeOnload();
    }
  } catch (e) {
    // accessing contentWindow failed
    errorFn();
  }
}

Тогда вы бы назвали это так из ваших тестов:

cy.get('iframe.stripe_checkout_app')
  .iframe()
  .find('input:eq(0)')
  .type("4000056655665556")

Ты можешь.alias () после звонка.iframe() ссылаться на него для остальных ваших входов или.get() Ифрейм несколько раз, я оставлю это на ваше усмотрение, чтобы выяснить.

Ваш ответ на вопрос