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

Need to upload and download methods, such as executing selene+selenoid not on the same server #504

Open
zhupengfarmer opened this issue Jan 12, 2024 · 1 comment

Comments

@zhupengfarmer
Copy link

like:
Selenide.$("").download();
Selenide.$("").uploadFile();

@yashaka
Copy link
Owner

yashaka commented Jan 12, 2024

The philosophy of Selene is a bit different than the Selenide's one...

In Selenide the SelenideElement is a class of "all potentially useful commands", but not all commands will work in all actual cases...

In Selene, we try to keep selene.Element a class for only "commands that will for sure work in the majority of cases". Commands that may not always work, or looks "less general", or "will not work for mobile context, but only in web context" - we try to collect inside selene.command.*. For example, Selenide has something like $(selector).scroll() but Selene does not, instead it allows you to do the following:

from selene import comand

s(selector).perform(command.js.scroll_into_view)

By this we also follow the "Explicit is better than explicit" principle from Python's PEP20 – we explicitely tell that in this special case we have as workaround to use javascript simulation of scrolling, because native Selenium's automatic scrolling for some reason did not work...

All this does not mean we will not add something like download and upload. But i want to say, that the design of these commands may be different from the Selenide's one. Probably we add them like this:

from selene import comand

s(selector).perform(command.download)
s(selector).perform(command.uploadFile)

Probably we will think twice on adding uploadFile, because usually you can use simple s(selector).send_keys(file_path) to achieve the same, so why to have two different commands to achieve almost the same? Recal another principle from the Python's PEP 20: “There should be one-- and preferably only one --obvious way to do it.”

In the cases where file uploading can't be achieved via send_keys, we are currently working on adding:

from selene import comand

s(droppable_area_selector).perform(command.js.drop_file('path/to/file.ext'))

It ↖️ will be available in the nearest release

Yet, Selene is considered as a "core library that allows you to do whatever you want by easily extending it with what you need". Thus, while working on the final 2.0 release we consider adding some official support for plugins, so you can quickly extend also the selene.Element with all commands you need.

For example, if you want the .scroll_into_view() command to be available on selene.Element too, you could do something like the following:

import selene
from selene import command

class MyCustomElement(selene.Element):
    def scroll_into_view(self):
        return self.perform(command.js.scroll_into_view)
        
browser: selene.Browser[MyCustomElement, selene.Collection] = selene.browser.with_(element_constructor=MyCustomElement)

# or

browser: selene.Browser[MyCustomElement, selene.Collection] = selene.Browser(Config(element_constructor=MyCustomElement))

# then you can use:

browser.element('#some-button').scroll_into_view()

# or define your own version of s(selector)

def s(selector):
    return browser.element(selector)
    
   
# and
    
s('#some-button').scroll_into_view()

Same would apply to commands like download and upload.

The syntax from the last example is not final, this was just an example of showing you what approximately will be possible in final 2.0 release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants