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

Imporve the indexing function for the pages screenshot. #1840

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/SeleniumLibrary/__init__.pyi
Expand Up @@ -13,7 +13,7 @@ class SeleniumLibrary:
def alert_should_not_be_present(self, action: str = 'ACCEPT', timeout: Optional[Optional[datetime.timedelta]] = None): ...
def assign_id_to_element(self, locator: Union[selenium.webdriver.remote.webelement.WebElement, str], id: str): ...
def capture_element_screenshot(self, locator: Union[selenium.webdriver.remote.webelement.WebElement, None, str], filename: str = 'selenium-element-screenshot-{index}.png'): ...
def capture_page_screenshot(self, filename: str = 'selenium-screenshot-{index}.png'): ...
def capture_page_screenshot(self, filename: str = 'selenium-screenshot-{index} or {random} or {timestamp}.png'): ...
def checkbox_should_be_selected(self, locator: Union[selenium.webdriver.remote.webelement.WebElement, str]): ...
def checkbox_should_not_be_selected(self, locator: Union[selenium.webdriver.remote.webelement.WebElement, str]): ...
def choose_file(self, locator: Union[selenium.webdriver.remote.webelement.WebElement, str], file_path: str): ...
Expand Down
48 changes: 39 additions & 9 deletions src/SeleniumLibrary/keywords/screenshot.py
Expand Up @@ -14,20 +14,34 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from datetime import datetime
import random
from typing import Union

from robot.utils import get_link_path
from selenium.webdriver.remote.webelement import WebElement

from SeleniumLibrary.base import LibraryComponent, keyword
from SeleniumLibrary.utils.path_formatter import _format_pathr
from SeleniumLibrary.utils.path_formatter import _format_patht
from SeleniumLibrary.utils.path_formatter import _format_path

DEFAULT_FILENAME_PAGE = "selenium-screenshot-{index}.png"
DEFAULT_FILENAME_PAGE = "selenium-screenshot-{random}.png"
DEFAULT_FILENAME_ELEMENT = "selenium-element-screenshot-{index}.png"
EMBED = "EMBED"

TIMESTAMP = "timestamp"
RAND = "random"
LOW_LIMIT_RANDOM = 10**4
UPPER_LIMIT_RANDOM = 10**8






class ScreenshotKeywords(LibraryComponent):

@keyword
def set_screenshot_directory(self, path: Union[None, str]) -> str:
"""Sets the directory for captured screenshots.
Expand Down Expand Up @@ -201,16 +215,31 @@ def _get_screenshot_path(self, filename):
directory = self._screenshot_root_directory or self.log_dir
else:
directory = self.log_dir
filename = filename.replace("/", os.sep)
filename = filename.replace("/", os.sep)

index = 0
while True:
index += 1
formatted = _format_path(filename, index)
path = os.path.join(directory, formatted)
# filename didn't contain {index} or unique path was found
if formatted == filename or not os.path.exists(path):
return path

if RAND in filename:
indexation = str(random.randint(LOW_LIMIT_RANDOM, UPPER_LIMIT_RANDOM))
formatted = _format_pathr(filename, indexation)
path = os.path.join(directory, formatted)
if formatted == filename or not os.path.exists(path):
return path
elif TIMESTAMP in filename:
indexation = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
formatted = _format_patht(filename, indexation)
path = os.path.join(directory, formatted)
# filename didn't contain {index} or unique path was found
if formatted == filename or not os.path.exists(path):
return path
elif 'index' in filename:
index+=1
formatted = _format_path(filename, index)
path = os.path.join(directory, formatted)
# filename didn't contain {index} or unique path was found
if formatted == filename or not os.path.exists(path):
return path

Copy link
Member

Choose a reason for hiding this comment

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

Just a quick read of this I believe there is a logic error here where if none of the three are in the filename one will get themselves into an infinite loop.

def _create_directory(self, path):
target_dir = os.path.dirname(path)
if not os.path.exists(target_dir):
Expand All @@ -235,3 +264,4 @@ def _embed_to_log_as_file(self, path, width):
f'<a href="{src}"><img src="{src}" width="{width}px"></a>',
html=True,
)

11 changes: 11 additions & 0 deletions src/SeleniumLibrary/utils/path_formatter.py
Expand Up @@ -15,10 +15,21 @@
# limitations under the License.



def _format_path(file_path, index):
return file_path.format_map(_SafeFormatter(index=index))


def _format_pathr(file_path, random):
return file_path.format_map(_SafeFormatter(random=random))

def _format_patht(file_path, timestamp):
return file_path.format_map(_SafeFormatter(timestamp=timestamp))





class _SafeFormatter(dict):
def __missing__(self, key):
return f"{{{key}}}"