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

Change type to var #6

Open
wants to merge 35 commits into
base: master
Choose a base branch
from
Open

Change type to var #6

wants to merge 35 commits into from

Conversation

ufjena
Copy link

@ufjena ufjena commented Apr 12, 2021

No description provided.

@ufjena ufjena requested a review from occupant23 April 12, 2021 19:54
Copy link
Contributor

@occupant23 occupant23 left a comment

Choose a reason for hiding this comment

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

see the first comments

};

@Given("^login page is loaded$")
@Step("open login page")
public static LoginPage loginPage()
{
// open login page and check for expected page
LoginPage loginPage = homepage().userMenu.openLogin();
var loginPage = homepage().userMenu.openLogin();
loginPage.isExpectedPage();
Copy link
Contributor

Choose a reason for hiding this comment

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

change to return loginPage.isExpectedPage(); so avoid one extra line

@@ -42,7 +40,7 @@ public static LoginPage loginPage()
public static RegisterPage registerPage()
{
// open login page and check for expected page
RegisterPage registerPage = homepage().userMenu.openRegister();
var registerPage = homepage().userMenu.openRegister();
registerPage.isExpectedPage();
Copy link
Contributor

Choose a reason for hiding this comment

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

change to return loginPage.isExpectedPage(); so avoid one extra line

@@ -33,24 +33,24 @@ public OrderSupport(GlobalStorage storage)
@Given("^new user with \"([^\"]*)\", \"([^\"]*)\", \"([^\"]*)\", \"([^\"]*)\" is registered and logged in$")
public void registerAndLogIn(String firstName, String lastName, String email, String password)
{
RegisterPage registerPage = OpenPageFlows.registerPage();
var registerPage = OpenPageFlows.registerPage();
registerPage.isExpectedPage();
Copy link
Contributor

Choose a reason for hiding this comment

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

Please check all "Support" classes. We should have added the isExpectedPage already in the open function for the page. so a second call should not be needed.

OrderHistoryPage orderHistory = accountOverview.openOrderHistory();
var accountOverviewPage = new HomePage().userMenu.openAccountOverview();
accountOverviewPage.isExpectedPage();
var orderHistoryPage = accountOverviewPage.openOrderHistory();
for (Product product : storage.products)
Copy link
Contributor

Choose a reason for hiding this comment

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

Be consistent for structures like:

for (Product product : storage.products){...}

Decide if we use Product product : or var product : and adjust it at all occurrences.
BTW: I would use Product product : since this is a little bit more readable if you are working on class fields.

@oomelianchuk oomelianchuk self-assigned this May 19, 2021
Copy link
Contributor

@occupant23 occupant23 left a comment

Choose a reason for hiding this comment

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

@oomelianchuk Please look into the comments

{
clearBrowserCookies();
open(Neodymium.configuration().url() + url);
return new ProductdetailPage();
return new ProductDetailPage();
Copy link
Contributor

Choose a reason for hiding this comment

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

please call isExpectedPage() to validate the result

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

{
open(Neodymium.configuration().url() + url);
return new ProductdetailPage();
return new ProductDetailPage();
Copy link
Contributor

Choose a reason for hiding this comment

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

please call isExpectedPage() to validate the result

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

var cartPage = new CartPage();
cartPage.updateProductCountByName(name, style, size, amount);

var updateProduct = storage.getProductFromArrayList(name, size, style);
Copy link
Contributor

Choose a reason for hiding this comment

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

@oomelianchuk I think we can use storage.updateCountOfProduct() to shorten the code at this place.

Copy link
Contributor

Choose a reason for hiding this comment

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

You are right, done

@@ -38,8 +35,15 @@ public Product addProduct(Product product)
// increase amount of product if already there or add the whole product
if (products.contains(product))
{
Product updatedProduct = products.get(products.indexOf(product));
updatedProduct.setAmount(updatedProduct.getAmount() + 1);
var updatedProduct = products.get(products.indexOf(product));
Copy link
Contributor

Choose a reason for hiding this comment

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

@oomelianchuk Please reuse updateCountOfProduct if possible. We should not implement the same functions again.

Copy link
Contributor

Choose a reason for hiding this comment

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

Done


public class ProductSupport
{
@When("^product \"([^\"]*)\" is opened$")
public ProductdetailPage clickProductByName(String productName)
public ProductDetailPage clickProductByName(String productName)
Copy link
Contributor

Choose a reason for hiding this comment

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

@oomelianchuk is a return type needed at this place?
In general the Steps are not able to communicate with each other on this level, so please remove the return if it'n unused.

Copy link
Contributor

Choose a reason for hiding this comment

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

I couldn't find a reason, why we would need this. Removed

@@ -60,42 +59,42 @@ public void validateStructure()
$("#formAddDelAddr").shouldBe(visible);
Copy link
Contributor

Choose a reason for hiding this comment

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

@oomelianchuk Can we reuse the AddressForm at this place? und implement this functionality at one place?

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

{
// Credit Card Number
// Fills the card number field with the parameter
creditCardNumber.val(number);
creditCardNumber.val(card.getCardNumber());
Copy link
Contributor

Choose a reason for hiding this comment

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

@oomelianchuk Could we create a credit card form and reuse it at the possible places if the underlying form is the same?

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

String firstName = shippingAddress.getFirstName();
String lastName = shippingAddress.getLastName();
String fullName = firstName + " " + lastName;
shippingAddressForm.find(".name").shouldHave(exactText(fullName));
Copy link
Contributor

Choose a reason for hiding this comment

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

@oomelianchuk It would be nice to rename the shippingAddressForm to shippingAddressContainer or shippingAddressTile to avoid misunderstandings.

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

@oomelianchuk oomelianchuk requested a review from occupant23 May 19, 2021 15:32
Product updatedProduct = products.get(products.indexOf(product));
updatedProduct.setAmount(updatedProduct.getAmount() + 1);
return updatedProduct;
updateCountOfProduct(product.getName(), product.getSize(), product.getStyle(), product.getAmount() + 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

@oomelianchuk: if updateCountOfProduct would return the updated product we could save the second line of code

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

HomePage homePage = new HomePage();
homePage.isExpectedPage();
return homePage;
return new HomePage().isExpectedPage();
};
Copy link
Contributor

Choose a reason for hiding this comment

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

@oomelianchuk Please remove the ; after functions. They are not needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

}

@Step("open product page without cleared cookes")
public static ProductdetailPage openProductdetailsPage(String url)
// TODO check if needed - else delete
Copy link
Contributor

Choose a reason for hiding this comment

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

@oomelianchuk Please take care of the TODO

Copy link
Contributor

@oomelianchuk oomelianchuk May 20, 2021

Choose a reason for hiding this comment

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

The method is called in OrderSupport.openProductPageAndAddItoTheCart, so I just removed TODO

registerUser(storage.user);
// registerUser(storage.user);
var registerPage = OpenPageFlows.registerPage();
registerPage.isExpectedPage();
Copy link
Contributor

Choose a reason for hiding this comment

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

@oomelianchuk the isExpectedPage method should already have been called by the registerPage method.
If this is the case please remove the second call.

Copy link
Contributor

Choose a reason for hiding this comment

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

The method is not called anywhere, so I removed it completely

var registerPage = OpenPageFlows.registerPage();
registerPage.isExpectedPage();
var loginPage = registerPage.sendRegisterForm(storage.user);
loginPage.isExpectedPage();
Copy link
Contributor

Choose a reason for hiding this comment

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

@oomelianchuk the isExpectedPage method should already have been called by the sendRegisterForm method.
If this is the case please remove the second call.

Copy link
Contributor

Choose a reason for hiding this comment

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

The method is not called anywhere, so I removed it completely

storage.user = new User(firstName, lastName, eMail, password);
};

@Given("^login page is opened after registration$")
public void registerUserSetup()
{
// use the user coming from dependency injection
registerUser(storage.user);
// registerUser(storage.user);
Copy link
Contributor

Choose a reason for hiding this comment

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

@oomelianchuk BTW: what happened to this registerUser(storage.user); function. Please utilize it or remove it and the comment if it isn't needed anymore.

Copy link
Contributor

Choose a reason for hiding this comment

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

The method is not called anywhere, so I removed it completely

@oomelianchuk oomelianchuk requested a review from occupant23 May 20, 2021 15:02
@oomelianchuk
Copy link
Contributor

The method isPage added to AbstractPageObject and used in RegisterSupport.deleteUser

Product updatedProduct = products.get(products.indexOf(product));
updatedProduct.setAmount(updatedProduct.getAmount() + 1);
return updatedProduct;

Copy link
Contributor

Choose a reason for hiding this comment

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

remove unneeded new line

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

@oomelianchuk oomelianchuk requested a review from occupant23 June 4, 2021 11:05
Copy link
Contributor

@occupant23 occupant23 left a comment

Choose a reason for hiding this comment

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

@oomelianchuk go ahead please.

public void removeProduct(String name, String style, String size)
{
var updateProducht = getProductFromArrayList(name, size, style);
products.remove(products.indexOf(updateProducht));
Copy link
Contributor

Choose a reason for hiding this comment

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

is products.indexOf needed?

products.remove(updateProducht); should work as well

Copy link
Contributor

Choose a reason for hiding this comment

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

Done


public void removeProduct(String name, String style, String size)
{
var updateProducht = getProductFromArrayList(name, size, style);
Copy link
Contributor

Choose a reason for hiding this comment

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

rename updateProducht to product.
Maybe you can also delete the local variable and call it directly within the next line.

Copy link
Contributor

Choose a reason for hiding this comment

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

Done


public Product updateCountOfProduct(String name, String size, String style, int amount)
{
var updateProducht = getProductFromArrayList(name, size, style);
Copy link
Contributor

Choose a reason for hiding this comment

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

rename updateProducht to product.

Copy link
Contributor

Choose a reason for hiding this comment

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

Done

}

@Step("ensure the correct page was loaded")
public boolean isPage()
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if this kind of isPage is a good variant. maybe this can't be generalized.
This will catch the error, but error artifacts (images/source code) will be created nevertheless.

I guess this requires a specific implementation using something like has(condition) to prevent side effects.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is a tricky problem. I found 4 solutions for this but none of them is flawless.

  1. Make page objects implement both isPage and isExpectedPage methods. - IMO, this is code duplication, as isExpectedPage is just a rephrasing of isPage but with assertion.
  2. Turn off screenshots via com.codeborne.selenide.Configuration ( Configuration.screenshots=fasle; Configuration.savePageSource=fasle; ). The problem is that the com.codeborne.selenide.Configuration is not thread-safe, so, in case we use this approach, screenshots on failure will be disabled for all running tests for the time isPage method is executed.
  3. Make page objects implement only isPage method and create the following standard implementation of isExpectedPage method:
    @SuppressWarnings("unchecked")
    public <T extends AbstractPageObject> T isExpectedPage()
    {
        SelenideAddons.wrapAssertionError(() -> Assert.assertTrue("opened page is not the expected one", isPage()));
        return (T) this;
    }

This approach has multiple problems:

  • SuppressWarnings to make it possible for isExpectedPage method to return the page object
  • The exact information about failed assertion will be lost, which will make debugging more complicated
  1. During object creation add elements to check in the isExpectedPage/isPage method in the pageCharacteristics map, defined in AbstractPageObject. AbstractPageObject can then contain the following methods:
    @SuppressWarnings("unchecked")
    public <T extends AbstractPageObject> T isExpectedPage()
    {
        pageCharacteristics.forEach((element, condition) -> element.should(condition));
        return (T) this;
    }

    @Step("ensure the correct page was loaded")
    public boolean isPage()
    {
        LinkedList<Boolean> results = new LinkedList<>();
        pageCharacteristics.forEach((element, condition) -> results.add(element.has(condition)));
        return results.contains(false);
    }

This approach also has problems with casts but solves the problem with lost information about the failed assertion.
Instead, it introduces a relatively complicated and unclear structure to the project.

What approach do you prefer? Do you have any other ideas?

Copy link
Contributor

Choose a reason for hiding this comment

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

isPage method is removed

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.

3 participants