Jsf-Selenium integration

Husamoli345

Husamoli345

Mitglied
Hallo Leute,

habe eine Java-Server-Faces Seite entwickelt und möchte nun diese mit Selenium testen allerdings sagt er mir Fehler wie Invalid Session Id oder located element not visible wenn ich einen Button meiner Seite aufrüfen möchte.

Mit WebdriverWait und ImplycitlyWait hab ich es schon probiert ohne Erfolg gibt es besonderheiten auf die ich achten muss wenn ich mit Jsf arbeite?

Lg
 
Husamoli345

Husamoli345

Mitglied
Funktioniert:
@Test
    public void testButton() {
        d.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        WebElement buttonElement = d
                .findElement(By.xpath("/html[1]/body[1]/form[1]/table[1]/tbody[1]/tr[1]/td[7]/input[1]"));
        WebDriverWait wait = new WebDriverWait(d, 10);
        wait.until(ExpectedConditions.visibilityOf(buttonElement));
        buttonElement.click();
    }


Nach Aufruf meiner Seite drücke ich auf einen Update Button siehe Code oben dies funktioniert auch komme ich dann auf die Edit Seite und versuche dort ein Element auszuwählen findet er dies nicht..
 
Husamoli345

Husamoli345

Mitglied
Java:
<input id="form:name-id" type="text" name="form:name-id" value="Fabian" class="form-control" xpath="1">


So sieht der Eintrag nach Chropath aus aber über Xpath , classname oder id bekomme ich keinen Zugriff :&
 
Husamoli345

Husamoli345

Mitglied
Java:
<input id="form:name-id" type="text" name="form:name-id" value="May" class="form-control" xpath="1">


So sieht mein Cropath Eintrag aus.
   
   
    So mein findElement by.xpath Code
    d.findElement(By.xpath("//input[contains(@id, 'form:name-id')]")).sendKeys("");
    Thread.sleep(3000);

Wieso findet er dieses Textfeld nicht :/ habe es auch schon mit


Java:
    WebDriverWait wait = new WebDriverWait(d, 10);
        wait.until(ExpectedConditions.visibilityOf(testUpdateButtonElement));


versucht.
 
Flown

Flown

Administrator
Mitarbeiter
Wenn du eine Id hast, warum brauchst du einen xpath. Es gibt ja ein by.id
 
mihe7

mihe7

Top Contributor
JSF-IDs und HTML-IDs sind nicht unbedingt identisch. Am einfachsten ist es, wenn Du die Seite im Browser öffnest, das Kontextmenü des Browsers für das betreffende Element öffnest und dort mal "Inspect Element" (oder Element untersuchen o. ä.) auswählst. Dort solltest Du dann die korrekte ID sehen.
 
Husamoli345

Husamoli345

Mitglied
Dies habe ich schon gemacht leider ohne Erfolg... aber an JSF muss es nicht unbedingt liegen das ich Schwierigkeiten habe?
 
Husamoli345

Husamoli345

Mitglied
Da sich das Element zum ändern in einem <div verbindet probier ich noch die Möglichkeit des JavaScript Executors..
 
Husamoli345

Husamoli345

Mitglied
Java:
@Test
    private void testUpdateButton() throws InterruptedException {
        d.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        WebElement clickElement = d.findElement(By.cssSelector("table.table.table-striped.table-hover.table-bordered.tableUpdated:nth-child(2) tbody:nth-child(2) tr:nth-child(1) td:nth-child(7) > input.btn.btn-primary"));
        String mainWindow = d.getWindowHandle();
        System.out.println(mainWindow);
        clickElement.click();
        
        Set<String> windowHandels = d.getWindowHandles();
        Thread.sleep(3000);
        for(String window : windowHandels) {
            if (!window.equals(mainWindow)) {
                d.switchTo().window(window); {
                    WebElement nameField = d.findElement(By.xpath("//input[@id='form:id']"));
                    nameField.click();
                    Thread.sleep(4000);
                    nameField.sendKeys("Hallo");
                    try {
                        Thread.sleep(3000);
                    } catch(InterruptedException e) {
                        e.printStackTrace();
                    }
                    
                }
                
            }
            
        }


Wenn ich dies auführe zeigt er keinen Fehler an aber macht es auch nicht wirklich zumindestens seh ich nichts beim Testdurchlauf..
 
mihe7

mihe7

Top Contributor
Dies habe ich schon gemacht leider ohne Erfolg... aber an JSF muss es nicht unbedingt liegen das ich Schwierigkeiten habe?

JSF ohne Ajax rendert das HTML serverseitig - das ist so ziemlich das einfachste. Problematisch sollte es erst werden, wenn Ajax dazukommt bzw. der DOM anderweitig während der Laufzeit verändert wird :p Was macht denn der Button beim Klick?
 
Husamoli345

Husamoli345

Mitglied
Ajax ist nicht vorhanden in meiner Anwendung daher verwunderts mich es Ja so.

Bei Klick des Buttons sollen alle Einträge eigentlich aktualisiert werden. Es soll aber erstmal das Textfeld gefunden werden und ein Eintrag erfolgen daran haberts noch.
 
mihe7

mihe7

Top Contributor
Was auch manchmal ein Problem macht - abhängig davon, wie man abfragt - ist der Doppelpunkt in den IDs. Bei einem <div id="a:b">:

Javascript:
// OK:
document.getElementById("a:b")

// auch als CSS-Selektor
document.querySelector("#a\\:b")

/*
Ungültig: 
document.querySelector("#a:b")
document.querySelector("#a\:b")
*/
 
Husamoli345

Husamoli345

Mitglied
Java:
@Test
   private void textChangePassword() throws InterruptedException {
        WebElement textChanging3 = d.findElement(By.id("form:password"));
        textChanging3.clear();
        textChanging3.sendKeys("secret");
        Thread.sleep(3000);
    }

Mit diesem Code findet er das TextElement und sendet auch die Einträge 😦 nun findet er aber den UpdateButton nichtmehr komisch komisch ich arbeite weiter dran :)
 
Husamoli345

Husamoli345

Mitglied
Java:
<input id="form:updatebtn" type="submit" name="form:updatebtn" value="Update" class="btn btn-primary updateBtnStyle" xpath="1">



@Test
    private void pressUpdateButton() throws InterruptedException {
        WebElement pressupdateButton = d.findElement(By.xpath("//input[@id='form:updatebtn']"));
        pressupdateButton.click();
        
    }
Dieser Button wird leider nicht gefunden weder mit xpath noch mit id oder css selector aber ich hab echt kein schimmer warum..
 
Husamoli345

Husamoli345

Mitglied
Ich arbeite auch weiter dran sobald ich eine Lösung gefunden habe meld ich mich danke für deine Hilfe.
 
Husamoli345

Husamoli345

Mitglied
Java:
<input type="submit" name="form:j_idt34" value="Update" class="btn btn-primary updateBtnStyle" xpath="1">

so siehts jetzt aus


Java:
    @Test
    private void pressUpdateButton1() throws InterruptedException {
    //    d.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);
        WebDriverWait wait = new WebDriverWait(d, 10);
        WebElement pressbuttonElement = wait
                .until(ExpectedConditions.visibilityOfElementLocated(By.id("form:j_idt34")));
        Thread.sleep(5000);
        pressbuttonElement.submit();




sagt aber auch das es nicht gefunden wurde
 
mrBrown

mrBrown

Super-Moderator
Mitarbeiter
Jetzt hat der Button auch keine ID mehr, sondern nur den Namen – du suchst aber nach der ID.
 
Husamoli345

Husamoli345

Mitglied
Ich hab den Button jetzt eine Id zugewiesen
Java:
 <div class="form-group">
                <div class="col-sm-2"></div>
                <div class="col-sm-4"><input id="form:updateBtn" type="submit" name="form:updateBtn" value="Update" class="btn btn-primary updateBtnStyle" />
                </div>


Aber weiter komme ich mit
Java:
    WebElement clickupdate = d.findElement(By.id("form:updateBtn"));
auch nicht.
 
mihe7

mihe7

Top Contributor
Ich weiß nicht, was Du da betreibst, ich habe das mal nachgestellt -> funktioniert einwandfrei.
 

Anhänge

  • selenium-test.zip
    6 KB · Aufrufe: 2
mihe7

mihe7

Top Contributor
Das glaub ich nicht. Es wird an Deinem Code liegen, den wir nicht vollständig kennen. Schreib mal eine minimale Testklasse, bei der das Problem auftritt - zusammen mit einer minimalen JSF-Seite.
 
Husamoli345

Husamoli345

Mitglied
Also
Erste Seite:
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:cc="http://java.sun.com/jsf/composite"
>
    
<h:head>
    <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1" http-equiv="X-UA-Conpatible" />
    <h:outputStylesheet library="css" name="bootstrap.min.css" />     
    <title>JSF CRUD Example</title>
    <style type="text/css">
        .tableUpdated {
            width: 90% !important;
            margin: 17px 58px 0 !important;
        }
        .btnSpace {
            margin: 17px;
        }     
    </style>
</h:head>
<h:body>
    <center><h2><h:outputText value="Student Records"/></h2></center>
    <h:form id="studentForm">
        <h:dataTable id="studentTable" binding="#{table}" value="#{studentBean.studentsList()}" var="student" class="table table-striped table-hover table-bordered tableUpdated">
            <h:column>
                <f:facet name="header">Id</f:facet>
                <h:outputText value="#{table.rowIndex + 1}" />
            </h:column>
            <h:column>
                <f:facet name="header">Student Name</f:facet>
                <h:outputText value="#{student.name}" />
            </h:column>
            <h:column>
                <f:facet name="header">Email Address</f:facet>
                <h:outputText value="#{student.email}" />
            </h:column>
            <h:column>
                <f:facet name="header">Password</f:facet>
                <h:outputText value="#{student.password}" />
            </h:column>
            <h:column>
                <f:facet name="header">Gender</f:facet>
                <h:outputText value="#{student.gender}" />
            </h:column>
            <h:column>
                <f:facet name="header">Address</f:facet>
                <h:outputText value="#{student.address}" />
            </h:column>
            <h:column>
                <f:facet name="header">Update</f:facet>
                <h:commandButton  action="#{studentBean.editStudentRecord(student.id)}" value="Update" class="btn btn-primary" />
            </h:column>
            <h:column>
                <f:facet name="header">Delete</f:facet>
                <h:commandButton action="#{studentBean.deleteStudentRecord(student.id)}" value="Delete" class="btn btn-danger" id="btnupdate" />
            </h:column>
        </h:dataTable>
        <center>
            <h:commandButton action="createStudent.xhtml?faces-redirect=true" value="Create New User" class="btn btn-success btnSpace" id="btndelete" />
        </center>
    </h:form>
</h:body>
</html>





Zweite Seite:
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:cc="http://java.sun.com/jsf/composite"
>
 
<h:head>
    <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1" http-equiv="X-UA-Conpatible" />
    <h:outputStylesheet library="css" name="bootstrap.min.css" />
    <title>JSF CRUD Example</title>
    <style type="text/css">
        .updateBtnStyle {
            width: 80px !important;         
        }
    </style>
</h:head>
<h:body>
        <h:form id="form" class="form-horizontal">
            <div class="form-group">
                <div class="col-sm-2"></div>
                <h2 style="text-align: center" class="col-sm-4">Bearbeiten des Eintrags</h2>
            </div>
            <hr/>
            <div class="form-group">
                <h:outputLabel for="username" class="control-label col-sm-2">User Name:</h:outputLabel>
                <div class="col-sm-4">
                    <h:inputText id="id" value="#{editRecordObj.name}" class="form-control" />
                </div>
            </div>
            <div class="form-group">
                <h:outputLabel for="email" class="control-label col-sm-2">Email:</h:outputLabel>
                <div class="col-sm-4">
                    <h:inputText id="email" value="#{editRecordObj.email}" class="form-control"/>
                </div>
            </div>
            <div class="form-group">
                <h:outputLabel for="password" class="control-label col-sm-2">Password:</h:outputLabel>
                <div class="col-sm-4">
                    <h:inputSecret id="password" value="#{editRecordObj.password}" class="form-control" autocomplete="off"  />
                </div>
            </div>
            <div class="form-group">
                <h:outputLabel for="gender" class="control-label col-sm-2">Gender:</h:outputLabel>
                <div class="col-sm-4">
                    <h:selectOneRadio id="genderbutton" value="#{editRecordObj.gender}">
                        <f:selectItem itemValue="M" itemLabel="Male" /><f:selectItem itemValue="F" itemLabel="Female" />
                    </h:selectOneRadio>
                </div>
            </div>
            <div class="form-group">
                <h:outputLabel for="address" class="control-label col-sm-2">Address:</h:outputLabel>
                <div class="col-sm-4">
                    <h:inputTextarea value="#{editRecordObj.address}" cols="50" rows="5" class="form-control"/>
                </div>
                <h:commandButton id="updatebutton" type="submit"  value="Update" action="#{studentBean.updateStudentDetails(editRecordObj)}" class="btn btn-primary updateBtnStyle"  />
            </div>
            <div class="form-group">
                <div class="col-sm-2"></div>
                <div class="col-sm-4">
                    
                </div>
            </div>
        </h:form>
    </h:body>
</html>




und die Selenium Klasse


Java:
import java.sql.Time;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class Seleniumtesting2 {

    WebDriver d = new ChromeDriver();
    WebDriverWait wait = new WebDriverWait(d, 20);
    private String baseUrl;
    JavascriptExecutor js = ((JavascriptExecutor) d);

    @BeforeClass
    public void setUp() throws InterruptedException {
        // System Set Property kann hier stehen falls es initaliziert wird
        d = new ChromeDriver();
        baseUrl = "http://localhost:8090/JSFLoginExample/";
        d.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        d.manage().window().maximize();
        Thread.sleep(5000);
        d.get(baseUrl);

    }

    @Test
    private void testUpdateButton() throws InterruptedException {
        d.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        WebElement clickElement = d.findElement(By.cssSelector("table.table.table-striped.table-hover.table-bordered.tableUpdated:nth-child(2) tbody:nth-child(2) tr:nth-child(1) td:nth-child(7) > input.btn.btn-primary"));
        clickElement.click();
        Thread.sleep(3000);

    }
    
    
    @Test
    private void textChangeName() throws InterruptedException {
        d.manage().window().fullscreen();
        WebElement textChanging3 = d.findElement(By.id("form:id"));
        textChanging3.clear();
        textChanging3.sendKeys("fabiansuchan@aol.de");
        Thread.sleep(3000);
    }

    @Test
    private void textChangeEmail() throws InterruptedException {
        d.manage().window().fullscreen();
        WebElement textChanging3 = d.findElement(By.id("form:email"));
        textChanging3.clear();
        textChanging3.sendKeys("fabiansuchan@aol.de");
        Thread.sleep(3000);
    }

    @Test
    private void textChangePassword() throws InterruptedException {
        WebElement textChanging3 = d.findElement(By.id("form:password"));
        textChanging3.clear();
        textChanging3.sendKeys("secret");
        Thread.sleep(3000);
    }

    @Test
    private void pressUpdateButton1() throws InterruptedException {
        WebElement clickButton;
        clickButton = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("form:updatebutton")));
        Thread.sleep(5000);
        clickButton.click();

    }

    @AfterClass
    private void afterTest() throws InterruptedException {
        Thread.sleep(3000);
        d.close();
    }

}




Ich hab jetzt echt lang geschaut aber wenn ich nicht komplett blind bin ist doch alles so wie bei ihnen o_O
 
Husamoli345

Husamoli345

Mitglied
Ich hab mal für die Seite http://www.uitestpractice.com/Students/Form eine Testanwendung geschrieben.


Java:
package basicLocator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class TestLogin {

    public static void main(String[] args) throws InterruptedException {
        // 1.Schritt wenn man mit Selenium arbeitet
        // Ein Treiber Objekt erzeugen

        WebDriver d = new ChromeDriver();
        d.get("http://www.uitestpractice.com/Students/Form");
        d.findElement(By.id("firstname")).sendKeys("Hallo");
        Thread.sleep(6000);

        d.findElement(By.xpath("//button[contains(text(),'Submit')]")).click();

        Thread.sleep(3000);
        d.close();

    }
}


Das funktioniert....aber wieso es auf meiner Seite nicht funktioniert weder mit Id noch mit contains(text) 😩 ich steh aufm Schlauch.
 
Husamoli345

Husamoli345

Mitglied
Danke für die Helfenden Hände zur Lösung meines Problems es funktioniert jetzt nach 3 Tagen Kopfschmerzen alles wie gewollt.
 
Husamoli345

Husamoli345

Mitglied
Ich bin jetzt wirklich verwirrt und möchte es gerne verstehen.


Java:
package basicLocator;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class TestLogin {

    public static void main(String[] args) throws InterruptedException {
        // 1.Schritt wenn man mit Selenium arbeitet
        // Ein Treiber Objekt erzeugen

        WebDriver d = new ChromeDriver();
        d.get("http://localhost:8090/JSFLoginExample");
        d.findElement(By.xpath("//tbody/tr[1]/td[7]/input[1]")).click();
        Thread.sleep(6000);

        d.findElement(By.id("form:id")).sendKeys("Hallo");
        d.findElement(By.id("form:password")).sendKeys("Perta");

        d.findElement(By.id("form:updateBtn")).click();

        Thread.sleep(3000);
        d.close();

    }
}


Funktioniert 1A




import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class SeleniumTesting3 {

    WebDriver d = new ChromeDriver();
    WebDriverWait wait = new WebDriverWait(d, 20);
    private String baseUrl;
    JavascriptExecutor js = ((JavascriptExecutor) d);

    @BeforeClass
    public void setUp() throws InterruptedException {
        // System Set Property kann hier stehen falls es initaliziert wird
        d = new ChromeDriver();
        baseUrl = "http://localhost:8090/JSFLoginExample";
        d.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        Thread.sleep(5000);
        d.get(baseUrl);
    }
    
    
    @Test
    private void testUpdateButton() throws InterruptedException {
        d.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        WebElement clickElement = d.findElement(By.xpath("//tbody/tr[1]/td[7]/input[1]"));
        clickElement.click();
        Thread.sleep(3000);

    }
    

    @Test
    public void changeName() throws InterruptedException {
        WebElement f = d.findElement(By.id("form:id"));
        Thread.sleep(3000);
        f.sendKeys("Hallo");

    }
    

    @Test
    public void changepw() throws InterruptedException {
        WebElement g = d.findElement(By.id("form:password"));
        Thread.sleep(3000);
        g.sendKeys("My New Secret Pw");

    }
    


    @Test
    public void testbutton() throws InterruptedException {
        WebElement k = d.findElement(By.id("form:updateBtn"));
        Thread.sleep(3000);
        k.click();

    }
    
    
    
    @AfterClass
    private void afterTest() throws InterruptedException {
        Thread.sleep(3000);
        d.close();
    }

}



Dort findet er wieder die Ids nicht mein Problem ist wohl gelöst aber verstehen möcht ich trotzdem was daran faul ist.
 
Husamoli345

Husamoli345

Mitglied
Ja sie wechselt von /jsfloginexample.xhtml zu Edit student.xhtml und dann wieder zur Hauptseite aber es befindet sich kein Iframe in der Seite!

Wieso funktioniert alles ohne @test Annotation etc 4 Tage Kopfschmerzen gehabt
 
mihe7

mihe7

Top Contributor
Naja, Du bist damit abhängig von der Reihenfolge, in der die Tests ausgeführt werden. Wen Du beim Klick auf updateButton die Seite wechselst, dann sind im nächsten Test die Elemente natürlich nicht mehr vorhanden.

Du könntest eine @BeforeTest-Methode einfügen, die sicherstellt, dass jeder Test immer auf der gleichen Seite beginnt.
 
Husamoli345

Husamoli345

Mitglied
Sie sagten die Elemente sind nicht mehr vorhanden allerdings sind sie Ja eigentlich erst vorhanden wenn die Seite gewechselt wird durch den Button.click der Ja funktioniert.

Also entweder findet er die Id´s nicht oder er findet die Id aber den UpdateBtn nicht der Ja auch eine Id besitzt komisch komisch 🤕 ich bastel mal weiter.
 
mrBrown

mrBrown

Super-Moderator
Mitarbeiter
Der wesentliche Punkt in @mihe7's Kommentar ist, dass die Tests unabhängig voneinander und insbesondere nicht in fester Reihenfolge ausgeführt werden.

Es kann also sein, dass zu erst testbutton und danach testUpdateButton ausgeführt wird, es kann aber auch andersrum sein.

Du erwartest in den Tests aber, dass die Methoden in fester Reihenfolge ausgeführt werden, daher gehen die Tests schief.
 
Husamoli345

Husamoli345

Mitglied
So es funktioniert jetzt alles danke für euren lieben Input.


Java:
    @AfterClass
    private void afterTest() throws InterruptedException {
        WebElement textChanging3 = d.findElement(By.id("form:updateBtn"));
        Thread.sleep(3000);
        textChanging3.click();
        Thread.sleep(3000);
        d.close();
    }


Ich musste lediglich dies in @AfterClass packen statt in einen Test. 💪
 
mrBrown

mrBrown

Super-Moderator
Mitarbeiter
Gut, das geht natürlich, ist aber eher so die schlechteste Variante 😅

@AfterClass ist dafür da, dass man nach Abschluss der Tests aufräumen kann, zB würde man dort den Driver schließen – relevanten Test-Code sollte man dort aber nicht ausführen.


Deine Test-Methoden sehen aktuell sehr danach aus, als sollte es nur eine einzige Methode sein, und in dieser sollten sowohl Felder gefüllt als auch Buttons gedrückt werden.
Durch das Trennen in mehrere Tests und das ausführen von Logik in @AfterClass führt auf lange (und eigentlich auch auf kurze) Sicht nur zu Problemen.
 
Ähnliche Java Themen

Ähnliche Java Themen

Anzeige

Neue Themen


Oben