Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swag labs tests #3

Merged
merged 20 commits into from
Jan 10, 2021
Merged

Swag labs tests #3

merged 20 commits into from
Jan 10, 2021

Conversation

BarteKKmita
Copy link
Owner

@BarteKKmita BarteKKmita commented Dec 30, 2020

Ready to check

@klubi
Copy link

klubi commented Dec 30, 2020

w 90% przypadków do repo nie powinno się commitować plików konfiguracyjnych konkretnego IDE.
Tobie sugeruję również tego nie robić i wywalić cały folder .idea.

Copy link

@klubi klubi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skorzystam z tego, że masz otwartego PR i dorzucę kilka komentarzy "ogólnych".

  • pliki z danymi/ pliki suite dla testNG powinny "żyć" w src/test/resources w odpowiedniej strukturze, żeby można było je łatwo znaleźć
  • unikaj przechowywania danych w plikach, których otwarcie wymaga konkretnego programu (w szczególności licencjonowanego jak produkty Microsoft) - np używaj csv zamiast xlsx, moim zdaniem yaml się całkiem dobrze sprawdza.
  • nie dodawaj plików exe do repo, zamiast tego dodaj README.md i opisz wymagania jakie należy spełnić przed uruchomieniem projektu
  • odseparuj testy od domeny (PageObjects, itd) najlepiej wrzuć pliki domenowe do src/main/java ułatwia to nawigację, ponieważ możesz wtedy PO trzymać w strukturze zbliżonej do "wyglądu" strony a testy zorganizować np wg funkcjonalności
  • przeprojektuj DriverModule, zamiast tworzyć na starcie dwa obiekty Drivera stwórz obiekt agnostyczny, np Browser, który w zależności od jakiegoś propertasa będzie pod getDriver zwracał instancję drivera, który ma zostać użyty do testów
  • na tym etapie podaruj sobie jakiekolwiek raportowanie, jak nabierzesz wprawy, to załatwisz raporty przy użyciu listenerów z testNG
  • nie znam za bardzo Guice, ale wydaje mi się że możesz dodać do swoich PO dwie rzeczy, które mega Ci ułatwią pracę:
  1. wywalić konstruktor z każdego PO poprzez stworzenie klasy bazowej, która będzie używała metody adnotowanej @PostConstruct do wywołania PageFactory.initElements(this)
  2. do powyższej klasy bazowej dodać metodę abstrakcyjną, którą każdy PO będzie musiał zaimplementować, metoda public boolean isLoaded() powinna zwracać informację o tym, czy dana strona została w pełni załadowana (czy wszystkie "ważne" elementy zostały załadowane", w połączeniu ze wspomnianym wcześniej obiektem Browser pozwoli Ci to na napisanie kilku bardzo pomocnych metod, którę będą np weryfikowały czy strona na którą przechodzisz jest załadowana zanim zaczniesz na niej wykonywać jakiekolwiek akcje.

build.gradle Outdated Show resolved Hide resolved
build.gradle Outdated Show resolved Hide resolved
build.gradle Outdated Show resolved Hide resolved
build.gradle Outdated Show resolved Hide resolved
build.gradle Outdated Show resolved Hide resolved
src/test/java/com/learning/pages/SwagLabsLoginPage.java Outdated Show resolved Hide resolved
src/test/java/com/learning/pages/SwagLabsLoginPage.java Outdated Show resolved Hide resolved
src/test/java/com/learning/SwagLabsLoginPageTest.java Outdated Show resolved Hide resolved
build.gradle Outdated Show resolved Hide resolved
public abstract class PageBase {
public PageBase(WebDriver driver) {
PageFactory.initElements(driver, this);
}
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PostConstruct is deprecated since Java 11.
What do you think about this solution?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks fine, I'm however not sure if there won't be any side effects.

Copy link

@klubi klubi Jan 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems to not be deprecated, it was removed from sdk -> https://stackoverflow.com/a/55622713/2838206

But... it also looks like Guice does not support those annotations... so you'd have to figure out a different way to manage object lifecycle.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks fine, I'm however not sure if there won't be any side effects.

What do you mean? What are possible side effects?

Copy link
Owner Author

@BarteKKmita BarteKKmita Jan 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But... it also looks like Guice does not support those annotations... so you'd have to figure out a different way to manage object lifecycle.

Could you provide me some article or give me tips how to do it?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible side effect would be an NPE thrown during object creation. I don't know if that's even possible, but just a thing to keep in mind.

I can't provide you a solution to that, I only read one stackoverflow thread that Guice does not "respect" those annotations. I have no real work experience with Guice, so I can't tell how it can be done.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I choose Guice for this one to learn sth new but I see that Spring is the best :)

String expectedErrorMessage = "Epic sadface: Username is required";
//When
driver.get(swagLabsLoginPage.getSwagLabsURL());
waitForPageToLoad();
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this right usage of this method?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not exactly. There are still few that would have to be implemented, but it could look like this

browser.open(SwagLabsLoginPage.class)

Browser could be an wrapper on driver, hiding driver completely.
Benefits? No selenium classes in tests... just page objects and browser.

I'll try to modify this branch to show you how this can be done.

Copy link

@klubi klubi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More incoming:)

gradle/wrapper/gradle-wrapper.properties Outdated Show resolved Hide resolved
build.gradle Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
propertiesReader = new PropertiesReader();
}

public WebDriver getDriver() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method will create new driver object each time it's called.
Instead create WebDriver field, and then:

if (driver == null) {
    //same if you already have, but instead return, assign driver to field
}
return driver;

This will allow you to create and manage only one instance of driver.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I get it. We make sure here to have Singleton. Let me implement it.
This will be a good exercise.

Copy link
Owner Author

@BarteKKmita BarteKKmita Jan 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If method getDriver gets driver from the filed is it enough?
Are there situations where we want to run tests in multiple threads simultaneously?

src/main/java/com/learning/pages/PageBase.java Outdated Show resolved Hide resolved
@@ -29,8 +42,8 @@ void shouldGoToJunit5WebPage() {
@Test
void shouldFindElementOnGoogleWebSite() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try implementing stuff, so the test looks like this:

void shouldFindElementOnGoogleWebSite() {
    googleSearchPage.open().search("Getting grip on it!");
}

(GoogleSearchPage would have to be injected by Guice)

This way:

  • googleSearchPage is responsible for knowing it's own URL
  • googleSearchPage holds logic responsible for waiting for page to load
  • googleSearchPage holds logic about search business process
  • test is more readable
  • test contains only business steps, high level ones, not all interactions with browser
  • no selenium in tests (no WebElements, no driver)
  • close to none setup
  • tearDown could also be removed if cleanup was moved to Browser class and PreDestroy method.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have got close to requirements you provided but I think I need to see your Browser class to understand it.
But let's wait with that until I finish the rest.

@BarteKKmita BarteKKmita marked this pull request as draft January 5, 2021 15:14
implementation 'org.projectlombok:lombok:1.18.16'
annotationProcessor 'org.projectlombok:lombok:1.18.16'
testImplementation 'org.testng:testng:7.3.0'
implementation 'com.netflix.governator:governator:1.17.10'
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found governator which is library for managing lifecycle of objects for Guice but unfortunately I didn't manage to get it work with @PreDestroy. I will continue searching for solution later on.


@PreDestroy
public void closeBrowser(){
webDriver.close();
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This not working yet.

import org.openqa.selenium.support.PageFactory;

public abstract class PageBase implements Closeable {

Copy link
Owner Author

@BarteKKmita BarteKKmita Jan 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added close method for closing resources. I will delete it when get @PreDestroy ready.

build.gradle Show resolved Hide resolved
src/main/java/com/learning/browsers/DriverModule.java Outdated Show resolved Hide resolved
@BarteKKmita BarteKKmita requested a review from klubi January 9, 2021 12:44
@BarteKKmita BarteKKmita removed the request for review from klubi January 9, 2021 20:30
@BarteKKmita BarteKKmita requested a review from klubi January 10, 2021 10:06
@BarteKKmita BarteKKmita marked this pull request as ready for review January 10, 2021 10:31
Copy link

@klubi klubi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix conflicts before merging.

@BarteKKmita BarteKKmita merged commit fd141e5 into master Jan 10, 2021
@BarteKKmita BarteKKmita deleted the SwagLabsTests branch January 14, 2021 08:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants