Aucun élément trouvé à l'aide d'une erreur de localisation après le passage à l'iframe à l'aide du rapporteur
J'ai essayé de télécharger un PDF intégré à partir d'une page Web en utilisant le sélénium de rapporteur. Je suis actuellement bloqué sur le fait de devoir télécharger le fichier car j'ai toujours l'erreur suivante:
- Échec: aucun élément trouvé à l'aide du localisateur: par (sélecteur css, * [id = "download"])
Il ne trouve pas le bouton même après être passé au cadre.
J'ai également essayé l'approche indiquée dans la réponse ici où elle extrait la valeur de l'attribut src et va directement à l'URL mais même problème. Le bouton de téléchargement (icône) est introuvable.
Nous avons les mêmes exigences exactes où il suffit de cliquer sur l'icône de téléchargement intégrée dans le PDF qui se trouve à l'intérieur d'un iframe. Exemple de page comme celle-ci .
Voici mon extrait de code.
const iframe = $('#printFrame'), downloadBtn = $('#download'),
content = $('#content');
await this.disableWaitForAngular();
await browser.wait(EC.visibilityOf(iframe),waitTimeout);
console.log("Switching to iframe...");
await browser.switchTo().frame(iframe.getWebElement());
await browser.wait(EC.visibilityOf(content), waitTimeout);
await browser.actions().mouseMove(content).perform();
console.log("Waiting for download button.");
await browser.wait(EC.visibilityOf(downloadBtn), waitTimeout);
await downloadBtn.click();
await browser.switchTo().defaultContent();
await this.enableWaitForAngular();
METTRE À JOUR:
J'ai essayé d'injecter le code suivant comme suggéré sur l'une des réponses proposées avant et après le changement de trame, mais cela me donne une erreur.
const downloadIcon: WebElement = await browser.executeScript('return document.querySelector("#viewer").shadowRoot.querySelector("#toolbar").shadowRoot.querySelector("#downloads").shadowRoot.querySelector("#download").shadowRoot.querySelector("#icon > iron-icon");');
await downloadIcon.click();
Erreur:
- Failed: javascript error: Cannot read property 'shadowRoot' of null
(Session info: chrome=87.0.4280.66)
(Driver info: chromedriver=87.0.4280.20 (c99e81631faa0b2a448e658c0dbd8311fb04ddbd-refs/branch-heads/4280@{#355}),platform=Windows NT 10.0.14393 x86_64)
Icône de téléchargement pour référence:

Réponses
Sur la page d'exemple que vous avez fournie, il n'y a pas de bouton "Télécharger", car ce bouton fait partie du navigateur et non de la page. Vous ne pouvez le trouver avec aucun type de sélecteur.
Mais nous y avons pdf
chargé comme un iframe
, afin que nous puissions créer notre propre bouton de téléchargement:
a = document.createElement('a'); a.href = $('iframe').src; a.download = "hello.pdf"; a.click();
Alors copiez ce code, allez sur votre page , collez-le dans la console et exécutez. Cela téléchargera le fichier.
C'est juste un exemple, mais peut-être que vous pouvez adapter cette idée à vos besoins.
METTRE À JOUR
Ok, je vais essayer d'expliquer ce qu'il y a sous le capot. Voici la même page dans différents navigateurs: Chrome, FF, Edge, IE.




Comme vous pouvez le voir, le "contenu interne" de la page PDF est différent, car ce n'est pas une page-ralative, il est contrôlé par le navigateur et ses plugins.
Appuyer sur l'icône / bouton "télécharger" équivaut à appuyer sur quelque chose à l'intérieur du plugin. Ce n'est pas possible.
En fait, la page elle-même ne contient que des objets PDF, pas les contrôles.
Par exemple, dans IE, vous ne pouvez pas localiser le bouton "télécharger". Il n'existe tout simplement pas, mais nous pouvons appuyer dessus ("dans le navigateur", pas "dans la page"), regardez:

Je pense que le problème que vous avez est dû à shadow-root.
Essayez d'utiliser la
by.deepCss(selector)
méthode Protractor. Si cela ne fonctionne pas, regardez la solution de contournement ici .Vous pouvez obtenir l' attribut src de l'iframe et l'ouvrir dans une nouvelle fenêtre. Puis sendKeys Ctrl + S.
Vous pouvez essayer d'exécuter en tant que code JavaScript dans rapporteur:
document.querySelector("#viewer").shadowRoot.querySelector("#toolbar").shadowRoot.querySelector("#downloads").shadowRoot.querySelector("#download").shadowRoot.querySelector("#icon > iron-icon").click();
Je reçois ceci en inspectant l'élément et en sélectionnant "Copier le chemin JS" dans Chrome DevTools.
Référence:
Comment interagir avec les éléments dans # shadow-root (open) lors de la suppression des données de navigation du navigateur Chrome à l'aide de cssSelector
deepCss ne parvient pas à identifier un élément à l'intérieur de la racine de l'ombre dans Protractor
Protractor: Impossible de sélectionner l'élément d'entrée dans un DOM shadow (Polymer ) en utilisant by.deepCss ('input')
https://www.protractortest.org/#/api?view=ProtractorBy.prototype.deepCss
https://superuser.com/questions/505899/keyboard-shortcuts-for-chrome-pdf-viewer
en rapporteur son anti-pattern pour mélanger enchaînement et attente ensemble:
isPDFDownloadSuccessful: () => Promise<boolean> = async() => {
await this.disableWaitForAngular(); //function equivalent to browser.waitForAngularEnabled(false);
const iframe = await element(by.tagName("iframe"));
console.log("Switching to iFrame...");
await browser.switchTo().frame(element(by.tagName('iframe')).getWebElement());
await element(by.id("download")).click()
//Insert here actions to check successful download
return true;
};
Ce code a fait le travail
await browser.waitForAngularEnabled(false);
await browser.get('https://www.sebi.gov.in/enforcement/orders/jun-2019/adjudication-order-in-respect-of-three-entities-in-the-matter-of-prism-medico-and-pharmacy-ltd-_43323.html');
let $iFrame = $('iframe[src*="sebi"]'),
$downloadButton = $('#download');
await browser.wait(ExpectedConditions.presenceOf($iFrame), 5000); await browser.switchTo().frame($iFrame.getWebElement());
await browser.wait(ExpectedConditions.presenceOf($downloadButton), 2000); await $downloadButton.click();
await browser.sleep(2500);
await browser.switchTo().defaultContent();
await browser.waitForAngularEnabled(true);
si cela ne fonctionne pas, il se peut qu'il y ait un problème avec votre configuration, vous devrez donc mettre à jour votre question et inclure son contenu