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

Add Element.upload() command #258

Closed
ElSnoMan opened this issue May 3, 2022 · 2 comments
Closed

Add Element.upload() command #258

ElSnoMan opened this issue May 3, 2022 · 2 comments
Assignees
Labels
beginner Small - requires some line changes and a test or two enhancement New feature or request

Comments

@ElSnoMan
Copy link
Owner

ElSnoMan commented May 3, 2022

Problem

Currently, if you want to upload a file to an element in Pylenium, you use the .type() command since that wraps .send_keys() from Selenium. Although it works, it's not explicit or intuitive. Instead, we should have an upload() command!

# Current solution

py.get("[input='upload-image']").type("path/to/file.png")

Solutions

I recommend adding a new .upload() method to our Element class!

Solution

# Something like this under the Element class

def upload(self, filepath: str) -> "Element":
    return self.type(filepath)

With a solution in place, focusing on an element feels much more explicit and makes sense 🎉

def test_upload(py: Pylenium):
    py.visit("https://the-internet.herokuapp.com/upload")
    py.get("#file-upload").upload(path/to/file.png)
    ...

Considerations

My current understanding is that you can only upload files to <input> elements. We could add a check to make sure the element is an <input> first and raise an error if it's not. The helpful error could save some headache, but this is something we should into a bit more.

@ElSnoMan ElSnoMan added enhancement New feature or request beginner Small - requires some line changes and a test or two labels May 3, 2022
@ElSnoMan ElSnoMan changed the title Add .upload() command to Element class Add Element.upload() command May 3, 2022
@ElSnoMan
Copy link
Owner Author

ElSnoMan commented Jun 28, 2022

This is the solution I will be adding to our next release:

def upload(self, filepath: str) -> "Element":
    self.py.log.debug(f"\t[STEP] .upload() - Select a file to upload: {filepath}")
    self.webelement.send_keys(filepath)
    return self

and I've tested it against two different versions of "uploading" I could find:

def test_upload_file(py: Pylenium, project_root):
    # 1. Test visible upload
    py.visit(f"{THE_INTERNET}/upload")
    py.get("#file-upload").upload(f"{project_root}/LICENSE")
    py.get("#file-submit").click()
    assert py.contains("File Uploaded!")

    # 2. Test hidden upload
    py.visit("https://practice.automationbro.com/cart/")
    py.get("#upfile_1").upload(f"{project_root}/he_badge.png")
    py.get("#upload_1").click()
    assert py.contains("uploaded successfully")

It seems the main benefits to using Element.upload() instead of Element.type() is:

  • upload(filepath: str) is more intuitive and explicit than type(*args)
  • Better logging since it would be clear that you performed an "upload" action instead of typing into something which could be confusing

However, the biggest drawback I ran into in designing and implementing this is that you still need to click() or submit() some "Upload Button" to complete the upload. This may not be as big a deal, but I was hoping that I could find a way to do both actions in a single command. The only thing that came up (so far) was something like the snippet below, but it didn't feel great to use:

def upload(self, filepath: str, element: "Element") -> "Element":
    self.webelement.send_keys(filepath)
    element.click() # or submit()?
    return self

# Usage

def test_upload_file(py: Pylenium, project_root):
    py.visit(f"{THE_INTERNET}/upload")
	upload_button = py.get("#file-submit")
    py.get("#file-upload").upload(f"{project_root}/LICENSE", upload_button)
    assert py.contains("File Uploaded!")

As always, I'm open to other suggestions and ideas, but we have a good solution for now 😄

@ElSnoMan ElSnoMan self-assigned this Jun 28, 2022
@ElSnoMan ElSnoMan closed this as completed Jul 6, 2022
@ElSnoMan
Copy link
Owner Author

ElSnoMan commented Jul 6, 2022

Released in v1.16.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
beginner Small - requires some line changes and a test or two enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant