pytest-watcher icon indicating copy to clipboard operation
pytest-watcher copied to clipboard

Offer option to clear screen after earch rerun

Open estevaoem opened this issue 4 years ago • 3 comments

Hello @olzhasar. First of all, thanks for your contribution, its really handy.

I'd suggest a little modification at the function

def _run_pytest(args) -> None:
    subprocess.run(["pytest", *args])

To something like

def _run_pytest(args, clear=False) -> None:
    if clear:
        subprocess.run(["clear"])
    subprocess.run(["pytest", *args])

To clear the results before each test.

Thanks!!

estevaoem avatar Dec 28 '21 18:12 estevaoem

Hey @estevaoem, Thank you for your feedback and this suggestion!

I agree that clearing the screen can be really useful, but I am not sure if this can be achieved that easily and will work on all systems. I will take a time to evaluate possible ways to implement this.

Appreciate your idea!

olzhasar avatar Dec 30 '21 20:12 olzhasar

Yeah, true. I was doing some tests with subprocess.run(["clear"]) on docker and found that the TERM env var should be present on the container for it to work and I didnt find time yet to learn more about it. I'll come back here if I find something userfull to contribute. You can close the issue if you will 😂

estevaoem avatar Jan 03 '22 13:01 estevaoem

@olzhasar @estevaoem

Use os.system instead of subprocess.run

ipython (license BSD-3) has across-platform clear screen, ipython.utils.terminal::_term_clear():

if os.name == 'posix':
    def _term_clear():
        os.system('clear')
elif sys.platform == 'win32':
    def _term_clear():
        os.system('cls')
else:
    def _term_clear():
        pass

Used in its demo.

@estevaoem Interested in making a PR so we can demo it?

Edit (2022-10-30): Updated ipython links 8.2.0 -> 8.6.0

tony avatar Apr 11 '22 16:04 tony

@tony Thanks for providing this snippet. This approach looks good to me, but why do you think we need to use os.system? Does it have any advantages over subprocess.run in this case?

olzhasar avatar Oct 30 '22 15:10 olzhasar

why do you think we need to use os.system? Does it have any advantages over subprocess.run in this case?

I have no opinion on it, only since it was ipython's approach and they're widely used: so I expect it's robust.

tony avatar Oct 30 '22 19:10 tony

@tony, currently I'm using the following solution:

ptw --runner "pytest --picked --testmon ./test" with the following libraries for testing:

pyparsing==3.0.9
attrs==21.4.0
py==1.11.0
iniconfig==1.1.1
packaging==21.3
pluggy==1.0.0
pytest==7.1.2
pytest-testmon==1.3.4
colorama==0.4.5
coverage==6.4.2
docopt==0.6.2
pytest-picked==0.4.6
watchdog==2.1.9
pytest-watch==4.2.0
pytest-cov==3.0.0
pytest-mock==3.8.2

estevaoem avatar Oct 30 '22 19:10 estevaoem

any updates?

mazlum avatar Sep 18 '23 10:09 mazlum

May i propose a tricky solution, Ansi escape sequence:

  • the 2J to erase the entire screen
  • the H to put the cursor at 0,0 position
  • and a end="" to not ouput a new line

this can be summurized with print("\x1b[2J\x1b[H", end=""), tested on Windows 11 and Ubuntu 23.04 working great. since MacOS is *nix like this should also work :)

Pixailz avatar Sep 19 '23 07:09 Pixailz

any updates?

I suspect the reason this issue is (and might stay) off the radar despite being marked as good first issue is that it requires testing on three separate platforms, which not everyone can do. @Pixailz did you try that in a throwaway script or a fork of pytest-watcher? If the latter I'd be happy to do more testing on Linux, and perhaps others can chime in for other platforms.

bard avatar Oct 23 '23 15:10 bard

I currently do not have much time to implement this. Will hopefully be able to work on that next month. In the meantime, PRs are welcome.

@bard The tricky part for me is testing on Windows machines, cause I personally don't use one. Another thing is testing for different terminal emulators on Linux, MacOS.

olzhasar avatar Oct 27 '23 10:10 olzhasar

@Pixailz looks quite hacky, will probably be hard to maintain that in future. But I appreciate the suggestion

olzhasar avatar Oct 27 '23 10:10 olzhasar

@olzhasar not that much, it's a specification to manipulate the terminal, this link easily show what's possible with ANSI Escaped Sequence. In fact that's just a sequence of character printed out to the terminal, and the terminal interpret those as "command", and it's pretty universal

to be honest i don't how to put this little print("\x1b[2J\x1b[H", end=""), but i'd be happy to make PR for you to test.

a little script to see if it work on OS's is available here

Pixailz avatar Oct 27 '23 10:10 Pixailz

The OG pytest-watch package had a -c option which was providing that functionality. Maybe it's worth checking out the implementation.

aaaaahaaaaa avatar Nov 16 '23 18:11 aaaaahaaaaa

@aaaaahaaaaa Good idea. Just to save people some hunting:


is_windows = sys.platform == 'win32'

# ...

def clear():
    """
    Clears the terminal.
    """
    subprocess.call('cls' if is_windows else 'clear', shell=True)

https://github.com/joeyespo/pytest-watch/blob/17375a1cf5be6d4dd30a583ffad61a0083d91b94/pytest_watch/helpers.py#L28C66-L28C66

bard avatar Nov 16 '23 19:11 bard

ANSI escape codes were specified in 1976 in the ECMA-48 standard, that's nearly 48 years ago, it's a pretty safe bet that it will be easy to support them for that many more years to come. Sending those escape codes is exactly what clear does (check out clear | hexdump -C), but it's much more efficient to do it directly.

The ones used in the snippet are called Erase Display and CUrsor Position, see wikipedia.

j0057 avatar Nov 21 '23 22:11 j0057

A new version with clear screen support has just been released. I ended up using the \033c sequence. It appears that it achieves the same result as the one suggested by @Pixailz, but is more concise.

Thank you everyone for your suggestions!

olzhasar avatar Jan 28 '24 14:01 olzhasar