Nie znaleziono elementu korzystającego z błędu lokalizatora po przełączeniu na element iframe przy użyciu kątomierza
Próbowałem pobrać osadzony plik PDF ze strony internetowej przy użyciu kątomierza selenu. Obecnie utknąłem na tym, że muszę faktycznie pobrać plik, ponieważ zawsze otrzymuję następujący błąd:
- Niepowodzenie: nie znaleziono elementu przy użyciu lokalizatora: według (selektor css, * [id = "pobieranie"])
Nie może znaleźć przycisku nawet po przełączeniu na ramkę.
Wypróbowałem również podejście wskazane w odpowiedzi tutaj, w którym wyodrębnia wartość atrybutu src i przechodzi bezpośrednio do adresu URL, ale ten sam problem. Nie można znaleźć przycisku pobierania (ikony).
Mamy te same dokładne wymagania, w których wystarczy kliknąć ikonę pobierania osadzoną w pliku PDF, który znajduje się wewnątrz elementu iframe. Przykładowa strona taka jak ta .
Oto mój fragment kodu.
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();
AKTUALIZACJA:
Próbowałem wstrzyknąć następujący kod zgodnie z sugestią jednej z proponowanych odpowiedzi przed i po przełączeniu ramek, ale wyświetla mi się błąd.
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();
Błąd:
- 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)
Ikona pobierania w celach informacyjnych:

Odpowiedzi
Na podanej stronie przykładowej nie ma przycisku „Pobierz”, ponieważ ten przycisk jest częścią przeglądarki, a nie stroną. Nie możesz go znaleźć za pomocą żadnego typu selektora.
Ale pdf
wczytaliśmy tam jako plik iframe
, więc możemy stworzyć własny przycisk pobierania:
a = document.createElement('a'); a.href = $('iframe').src; a.download = "hello.pdf"; a.click();
Więc skopiuj ten kod, przejdź do swojej strony , wklej go do konsoli i uruchom. Spowoduje to pobranie pliku.
To słuszny przykład, ale być może dostosujesz ten pomysł do swoich potrzeb.
AKTUALIZACJA
Ok postaram się wytłumaczyć co kryje się pod maską. Oto ta sama strona w różnych przeglądarkach: Chrome, FF, Edge, IE.




Jak widać, „zawartość wewnętrzna” strony PDF jest inna, ponieważ nie jest to ralatywa strony, jest kontrolowana przez przeglądarkę i jej wtyczki.
Naciśnięcie ikony / przycisku „pobierz” to to samo, co naciśnięcie czegoś wewnątrz wtyczki. To niemożliwe.
W rzeczywistości sama strona zawiera tylko obiekt PDF, a nie elementy sterujące.
Na przykład w IE nie możesz zlokalizować przycisku „pobierz”. Po prostu nie istnieje, ale możemy go nacisnąć („w przeglądarce”, a nie „na stronie”), spójrz:

Myślę, że problem, który masz, jest spowodowany korzeniem cienia.
Spróbuj użyć
by.deepCss(selector)
metody kątomierza. Jeśli to nie działa, spójrz na obejście tutaj .Możesz pobrać atrybut src elementu iframe i otworzyć go w nowym oknie. Następnie sendKeys Ctrl + S.
Możesz spróbować uruchomić jako kod JavaScript w kątomierz:
document.querySelector("#viewer").shadowRoot.querySelector("#toolbar").shadowRoot.querySelector("#downloads").shadowRoot.querySelector("#download").shadowRoot.querySelector("#icon > iron-icon").click();
Otrzymałem to podczas sprawdzania elementu i wybrałem opcję „Kopiuj ścieżkę JS” z Chrome DevTools.
Odniesienie:
Jak współdziałać z elementami w # shadow-root (open) podczas czyszczenia danych przeglądania przeglądarki Chrome za pomocą cssSelector
deepCss nie może zidentyfikować elementu wewnątrz katalogu głównego cienia w Protractor
Protractor: Nie można wybrać elementu wejściowego w cieniu DOM (Polymer ) przy użyciu by.deepCss ('input')
https://www.protractortest.org/#/api?view=ProtractorBy.prototype.deepCss
https://superuser.com/questions/505899/keyboard-shortcuts-for-chrome-pdf-viewer
w kątomierzu jego anty-wzór, aby połączyć łańcuch i oczekiwanie:
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;
};
Ten kod zadziałał
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);
jeśli to nie zadziała, może być coś nie tak z twoją konfiguracją, więc musisz zaktualizować swoje pytanie i dołączyć jego zawartość