> [name=Martin. S] > [time=Thu, Apr 20, 2023] > [name=Lucas. C] > [time=Thu, Apr 20, 2023] > [name=Lukas. B] > [time=Thu, Apr 20, 2023] > [name=Linus. S] > [time=Thu, Apr 20, 2023] # Selenium ## Teil 1 - Theorie ### 1. Recherchiert die verschiedenen Möglichkeiten, wie ihr HTML-Elemente mit Selenium lokalisieren. **ID based Search**: HTML-Elemente mit Selenium über seiner ID suchen. ```driver.find_element_by_id(ID)``` **Name based Search**: HTML-Elemente mit Selenium über seinem Namen suchen. ```driver.find_element_by_name("Name")``` **XPath based Search**: HTML-Elemente mit Selenium über einem XPath-Ausdruck suchen. ```driver.find_element_by_xpath("//div[@class='my-class']")``` **CSS-Class based Search**: HTML-Elemente mit Selenium über seiner CSS-Klasse suchen. ```driver.find_element_by_class_name("css-class-name")``` oder ```driver.find_element_by_css_selector(".css-class")``` **Link based Search**: HTML-Elemente mit Selenium über den Text eines Links suchen. ```driver.find_element_by_partial_link_text("Linktext")``` **Tag based Search**: HTML-Elemente mit Selenium über seinem Tag-Namen suchen. ```driver.find_element_by_tag_name("Tag")``` ### 2. Vergleicht die Methoden. Wie unterscheiden sich diese? In welchen Situationen würdet ihr die eine den anderen Varianten gegenüber bevorzugen? | Methode | Verwendungszweck | Unterschiede/ Vorteile | | --------------------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | | find_element_by_id(id) | Suche nach einem HTML-Element anhand der ID | Eindeutige ID, sollte nur einmal im Dokument vorkommen | | find_element_by_name(name) | Suche nach einem HTML-Element anhand des Namens | Der Name kann bei verschiedenen Elementen wiederverwendet werden, keine eindeutige Identifikation | | find_element_by_xpath(xpath) | Suche nach einem HTML-Element anhand des XPath-Ausdrucks | Sehr flexible Methode, erfordert jedoch Kenntnisse im Umgang mit XPath-Ausdrücken und ist etwas langsamer als andere Methoden | | find_element_by_class_name(name) | Suche nach einem HTML-Element anhand der CSS-Klasse | Einfache Methode, jedoch ist die CSS-Klasse möglicherweise bei verschiedenen Elementen wiederverwendet | | find_element_by_css_selector(css) | Suche nach einem HTML-Element anhand des CSS-Selektors | Sehr flexible Methode, erfordert jedoch Kenntnisse im Umgang mit CSS-Selektoren und ist etwas langsamer als andere Methoden | | find_element_by_link_text(text) | Suche nach einem HTML-Element anhand des vollständigen Texts eines Links | Funktioniert nur für anklickbare Links, ist jedoch sehr einfach und schnell zu verwenden | | find_element_by_partial_link_text(text) | Suche nach einem HTML-Element anhand eines Teils des Texts eines Links | Funktioniert nur für anklickbare Links, ist jedoch sehr einfach und schnell zu verwenden | | find_element_by_tag_name(name) | Suche nach einem HTML-Element anhand des Tags | Sehr einfach zu verwenden, aber möglicherweise nicht eindeutig genug | ### 3. Findet heraus, wie ihr Keyboard- & Mauseingaben simulieren könnt. Die Selenium-Webdriver-Bibliothek beinhaltet mehrere Methoden, wie man Keyboard- & Mauseingaben simulieren kann. Die wichtigsten Methoden zum Simulieren von Tastatureingaben und Mausklicks sind: **Tastatureingaben**: <ul style="list-style:none;"> <li>Taste und Tastenkombination simulieren <ul style="list-style:none"> <li><pre><code>.send_keys(Keys.KEY)</code></pre> </li> </ul> </li> <li>Tastatur-Texteingabe simulieren <ul style="list-style:none"> <li><pre><code>.send_keys("TEXT")</code></pre> </li> </ul> </li> <li>Drücken einer Taste simulieren <ul style="list-style:none"> <li><pre><code>.key_down(Keys.KEY)</code></pre> </li> </ul> </li> <li>Loslassen einer Taste simulieren <ul style="list-style:none"> <li><pre><code>.key_up(Keys.KEY)</code></pre> </li> </ul> </li> </ul> **Mausinteraktionen**: <ul style="list-style:none;"> <li>Mausklick auf ein Element simulieren <ul style="list-style:none"> <li><pre><code>.click()</code></pre></li> </ul> </li> <li>Rechtsklick auf ein Element simulieren <ul style="list-style:none"> <li><pre><code>.context_click()</code></pre></li> </ul> </li> <li>Doppelklick auf ein Element simulieren <ul style="list-style:none"> <li><pre><code>.double_click()</code></pre></li> </ul> </li> <li> Ziehen und Ablegen eines Elementes auf das Ziel simulieren <ul style="list-style:none"> <li><pre><code>.drag_and_drop(source, target)</code></pre></li> </ul> </li> <li> Bewegen der Maus auf ein Element simulieren <ul style="list-style:none"> <li><pre><code>.move_to_element(element)</code></pre></li> </ul> </li> <li> Drücken und Halten der Maustaste auf ein Element simulieren <ul style="list-style:none"> <li><pre><code>.click_and_hold(element)</code></pre></li> </ul> </li> <li> Loslassen der Maustaste simulieren <ul style="list-style:none"> <li><pre><code>.release()</code></pre></li> </ul> </li> </ul> ### 4. Erklärt vor welches Problem euch Webformulare oder andere Prozesse stellen, die eine längere Antwortzeit haben können. **Webformulare oder andere Prozesse, die eine längere Antwortzeit haben, können dazu führen, ...** ... dass Selenium auf eine Antwort vom Server wartet, die nicht kommen wird, bevor ein Timeout erreicht wird. Dies kann zu falschen Testergebnissen führen, da die Selenium-Test hängen bleiben. ... dass es dadurch zu asynchronen Anfragen kommt. In diesem Fall verliert Selenium die Synchronisation mit der Anwendung, da der Server länger braucht, um auf die Anfrage zu antworten. Somit ist der notwendige Zustand der Anwendung noch nicht erreicht ist, wenn Selenium versucht, auf Elemente zuzugreifen oder Aktionen auszuführen. ... dass es zu Frustration und Verwirrung bei den Benutzern führt, da sie nicht wissen, ob ihre Anfrage verarbeitet wird oder ob es ein Problem gibt. ... dass die Anwendung insgesamt langsamer wird, da alle Anfragen blockiert werden, bis die Verarbeitung der aktuellen Anfrage abgeschlossen ist. ### 5. Formuliert Lösungsvorschläge, mit welchen von Selenium bereitgestellten Mitteln ihr diesem Problem begegnen würdet. **Um diese Probleme zu lösen kann...** ... mit Selenium eine Wartezeit/Timeout auf ein bestimmtes Element mit Expected Conditions konfiguriert werden, um sicherzustellen, dass Selenium nicht zu lange auf eine Antwort vom Server wartet. ``` element = WebDriverWait(driver, 10).until( ExpectedConditions.presence_of_element_located(By.ID(ID) ); ``` ... kann '*implicitlyWait()*' verwendet werden, um dem WebDriver Zeit geben, auf die Antwort des Servers zu warten. Es ist jedoch wichtig zu beachten, dass '*implicitlyWait()*' nicht auf eine bestimmte Bedinungen wartet, sondern jediglich eine allgemeine Wartezeit. Deshalb sind die oben gennanten Lösung, meist besser geeignet. ``` driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); ``` ... kann '*Thread.sleep()*' verwendet werden, um den Code für eine bestimmte zeit anhalten, wenn Selenium auf ein längere Zeit auf eine Antwortzeit wartet. Dies ist jedoch keine zuverlässige Lösung, und die oben genannten Lösungen sind dafür viel besser geeignet. ``` Thread.sleep(T); ``` ### 6. Erforscht Möglichkeiten um Informationen (Status, Position, Inhalt, usw.) von Web-Elementen zu kommen. Die Selenium-Webdriver-Bibliothek beinhaltet verschiedene Möglichkeiten, um Informationen von Web-Elementen zu erhalten. Die wichtigsten Methoden sind: ``.getText()`` Mit dieser Methode kann der Textinhalt eines Elements abgerufen werden. ``.getAttribute()`` Mit dieser Methode können Attribute eines Elements (zB. href) abgerufen werden. ``.isEnabled()`` Mit dieser Methode kann überprüft werden, ob ein Element aktiviert oder deaktiviert ist. ``.isSelected()`` Mit dieser Methode kann überprüft werden, ob ein Element (zB. Checkbox-Element) ausgewählt ist oder nicht. ``.getLocation()`` Mit dieser Methode kann die Position eines Elements auf der Seite abgerufen werden. ``.getSize() `` Mit dieser Methode kann die Größe eines Elements abgerufen werden. ``.getTagName() `` Mit dieser Methode kann der Tag-Name eines Elements (zB. div) abgerufen werden. --- ## Teil 2 - Praxis ### Test #1 (Lukas) **basicTest** ```java /** * Test Selenium #1 */ @Test @Description("Der basic test soll testen ob der Driver geladen werden kann indem das Element 'Title' in der Quizme Seite gesucht wird.") public void basicTest() { driver.get("http://127.0.0.1:3000/"); String title = driver.getTitle(); assertEquals("Quiz Me", title); } ``` ### Test #2 (Linus) **landingPage** - Dieser Test prüft ob die Quizme Seite geladen wird indem das h1 Element mit dem Inhalt "Wilkommen bei QuizMe" angezeigt werden kann. ```java @Test public void containsH1() { driver.get("http://127.0.0.1:3000/"); var title = driver.findElement(By.tagName("h1")); assertNotNull(title); } ``` ### Test #3 (Lucas) **createLearnSet** - Dieser Test prüft ob das erstellen eines neuen Learnsets möglich sind. ```java @Test @Description("Create a new Learnset with name 'Learnset-1' DE -> GB") public void CreateLearnset() throws InterruptedException { // Navigate to the application URL driver.get("http://localhost:3000/"); // Click on the "Create" link driver.findElement(By.linkText("erstelle")).click(); // Enter the Learnset name WebElement learnsetName = driver.findElement(By.id("learnsetname")); learnsetName.click(); learnsetName.sendKeys("Learnset-1"); // Select the language WebElement languageDropdown = driver.findElement(By.id("language1")); languageDropdown.click(); languageDropdown.findElement(By.xpath("//option[. = 'Deutsch']")).click(); // Click the "Create" button driver.findElement(By.cssSelector(".btn")).click(); driver.get("http://localhost:3000/"); Thread.sleep(1000); assertEquals( "Learnset-1", driver.findElement(By.cssSelector("div.card:nth-child(1) > .name")); ); } ``` ### Test #4 (Lucas) **Enter Learnset** - Dieser Test prüft ob es Möglich ist in ein Lernset zu gehen. (?) ```java @Test @Description("Enter any learnset") public void EnterLearnset() { driver.get("http://localhost:3000/"); driver.findElement(By.cssSelector("div.card:nth-child(1) > .name")).click(); String expectedUrl = "http://localhost:3000/1"; String actualUrl = driver.getCurrentUrl(); assertEquals(expectedUrl, actualUrl); } ``` ### Test #5 (Lukas) **Create Learnwords** - Dieser Test prüft ob das erstellen von neuen Wörtern im Learnset möglich ist. ```java /** * Test Selenium #5 */ @Test @Description("Dieser Test prüft ob das erstellen von neuen Wörtern im Learnset möglich ist.") public void createLearnWord() throws InterruptedException { driver.get("http://localhost:3000/"); var element = new WebDriverWait(driver, Duration.ofSeconds(1)).until( ExpectedConditions.presenceOfElementLocated(By.tagName("strong")) ); driver.findElement(By.tagName("strong")).click(); driver.findElement(By.xpath("//th[text()='New']")).click(); driver.findElement(By.id("inp1")).sendKeys("Test1"); driver.findElement(By.id("inp2")).sendKeys("Test2"); driver.findElement(By.xpath("//button[text()='Send']")).click(); assertEquals("Test1", driver.findElement(By.xpath("//td[text()='Test1']")).getText()); assertEquals("Test2", driver.findElement(By.xpath("//td[text()='Test2']")).getText()); } ``` ### Test #6 (Linus) **Abfragen Learnwords** - Dieser Test prüft die Abfrage der Lernwörter und ob diese korrekt validiert werden. ```Java @Test @Description("Dieser Test prüft die Abfrage der Lernwörter und ob diese korrekt validiert werden.") public void checkCorrectWordValidation() throws InterruptedException { driver.get("http://localhost:3000/"); new WebDriverWait(driver, Duration.ofSeconds(1)).until( ExpectedConditions.presenceOfElementLocated(By.tagName("strong")) ).click(); new WebDriverWait(driver, Duration.ofSeconds(1)).until( ExpectedConditions.presenceOfElementLocated(By.linkText("Answer Mode")) ).click(); WebElement inpBox = driver.findElement(By.tagName("input")); inpBox.sendKeys("test 1"); driver.findElement(By.xpath("//*[text()='Enter']")).click(); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(1)); wait.until(ExpectedConditions.alertIsPresent()); Alert alert = driver.switchTo().alert(); String alertText = alert.getText(); assertEquals(alertText, "Correct!"); } ``` --- ## Teil 3 - Selenium IDE Es wurde eine Test recorderd, um einen neuen Learnset, mit denn Sprachen Englisch -> Deutsch erstellt. <img src="https://i.imgur.com/X7c4GU0.png" style="margin:2vh; filter:drop-shadow(0px 0px 5px black);">