434 lines
17 KiB
Python
434 lines
17 KiB
Python
"""
|
|
Creates a new SeleniumBase test file with boilerplate code.
|
|
|
|
Usage:
|
|
seleniumbase mkfile [FILE.py] [OPTIONS]
|
|
or sbase mkfile [FILE.py] [OPTIONS]
|
|
|
|
Example:
|
|
sbase mkfile new_test.py
|
|
|
|
Options:
|
|
--uc (UC Mode boilerplate using SB context manager)
|
|
-b / --basic (Basic boilerplate / single-line test)
|
|
-r / --rec (Adds Pdb+ breakpoint for Recorder Mode)
|
|
--url=URL (Makes the test start on a specific page)
|
|
|
|
Language Options:
|
|
--en / --English | --zh / --Chinese
|
|
--nl / --Dutch | --fr / --French
|
|
--it / --Italian | --ja / --Japanese
|
|
--ko / --Korean | --pt / --Portuguese
|
|
--ru / --Russian | --es / --Spanish
|
|
|
|
Syntax Formats:
|
|
--bc / --basecase (BaseCase class inheritance)
|
|
--pf / --pytest-fixture (sb pytest fixture)
|
|
--cf / --class-fixture (class + sb pytest fixture)
|
|
--cm / --context-manager (SB context manager)
|
|
--dc / --driver-context (DriverContext manager)
|
|
--dm / --driver-manager (Driver manager)
|
|
|
|
Output:
|
|
Creates a new SBase test file with boilerplate code.
|
|
If the file already exists, an error is raised.
|
|
By default, uses English with BaseCase inheritance,
|
|
and creates a boilerplate with common SeleniumBase
|
|
methods: "open", "type", "click", "assert_element",
|
|
and "assert_text". If using the basic boilerplate
|
|
option, only the "open" method is included. Only the
|
|
BaseCase format supports Languages or Recorder Mode.
|
|
UC Mode automatically uses English with SB() format.
|
|
"""
|
|
import codecs
|
|
import colorama
|
|
import os
|
|
import sys
|
|
|
|
|
|
def invalid_run_command(msg=None):
|
|
exp = " ** mkfile **\n\n"
|
|
exp += " Usage:\n"
|
|
exp += " seleniumbase mkfile [FILE.py] [OPTIONS]\n"
|
|
exp += " OR sbase mkfile [FILE.py] [OPTIONS]\n"
|
|
exp += " Example:\n"
|
|
exp += " sbase mkfile new_test.py\n"
|
|
exp += " Options:\n"
|
|
exp += " --uc (UC Mode boilerplate using SB context manager)\n"
|
|
exp += " -b / --basic (Basic boilerplate / single-line test)\n"
|
|
exp += " -r / --rec (Adds Pdb+ breakpoint for Recorder Mode)\n"
|
|
exp += " --url=URL (Makes the test start on a specific page)\n"
|
|
exp += " Language Options:\n"
|
|
exp += " --en / --English | --zh / --Chinese\n"
|
|
exp += " --nl / --Dutch | --fr / --French\n"
|
|
exp += " --it / --Italian | --ja / --Japanese\n"
|
|
exp += " --ko / --Korean | --pt / --Portuguese\n"
|
|
exp += " --ru / --Russian | --es / --Spanish\n"
|
|
exp += " Syntax Formats:\n"
|
|
exp += " --bc / --basecase (BaseCase class inheritance)\n"
|
|
exp += " --pf / --pytest-fixture (sb pytest fixture)\n"
|
|
exp += " --cf / --class-fixture (class + sb pytest fixture)\n"
|
|
exp += " --cm / --context-manager (SB context manager)\n"
|
|
exp += " --dc / --driver-context (DriverContext manager)\n"
|
|
exp += " --dm / --driver-manager (Driver manager)\n"
|
|
exp += " Output:\n"
|
|
exp += " Creates a new SBase test file with boilerplate code.\n"
|
|
exp += " If the file already exists, an error is raised.\n"
|
|
exp += " By default, uses English with BaseCase inheritance,\n"
|
|
exp += " and creates a boilerplate with common SeleniumBase\n"
|
|
exp += ' methods: "open", "type", "click", "assert_element",\n'
|
|
exp += ' and "assert_text". If using the basic boilerplate\n'
|
|
exp += ' option, only the "open" method is included. Only the\n'
|
|
exp += " BaseCase format supports Languages or Recorder Mode.\n"
|
|
exp += " UC Mode automatically uses English with SB() format.\n"
|
|
if not msg:
|
|
raise Exception("INVALID RUN COMMAND!\n\n%s" % exp)
|
|
elif msg == "help":
|
|
print("\n%s" % exp)
|
|
sys.exit()
|
|
else:
|
|
raise Exception("INVALID RUN COMMAND!\n\n%s\n%s\n" % (exp, msg))
|
|
|
|
|
|
def main():
|
|
c1 = ""
|
|
c5 = ""
|
|
c7 = ""
|
|
cr = ""
|
|
if "linux" not in sys.platform:
|
|
c1 = colorama.Fore.BLUE + colorama.Back.LIGHTCYAN_EX
|
|
c5 = colorama.Fore.RED + colorama.Back.LIGHTYELLOW_EX
|
|
c7 = colorama.Fore.BLACK + colorama.Back.MAGENTA
|
|
cr = colorama.Style.RESET_ALL
|
|
|
|
basic = False
|
|
use_uc = False
|
|
help_me = False
|
|
recorder = False
|
|
error_msg = None
|
|
start_page = None
|
|
invalid_cmd = None
|
|
syntax = "BaseCase"
|
|
language = "English"
|
|
|
|
command_args = sys.argv[2:]
|
|
file_name = command_args[0]
|
|
if file_name == "-h" or file_name == "--help":
|
|
invalid_run_command("help")
|
|
elif not file_name.endswith(".py"):
|
|
error_msg = 'File name must end with ".py"!'
|
|
elif "*" in file_name or len(str(file_name)) < 4:
|
|
error_msg = "Invalid file name!"
|
|
elif file_name.startswith("-"):
|
|
error_msg = 'File name cannot start with "-"!'
|
|
elif "/" in str(file_name) or "\\" in str(file_name):
|
|
error_msg = "File must be created in the current directory!"
|
|
elif os.path.exists(os.getcwd() + "/" + file_name):
|
|
error_msg = 'File "%s" already exists in this directory!' % file_name
|
|
if error_msg:
|
|
error_msg = c5 + "ERROR: " + error_msg + cr
|
|
invalid_run_command(error_msg)
|
|
|
|
if len(command_args) >= 2:
|
|
options = command_args[1:]
|
|
for option in options:
|
|
option = option.lower()
|
|
if option == "-h" or option == "--help":
|
|
help_me = True
|
|
elif option.startswith("--url=") and len(option) > 6:
|
|
from seleniumbase.fixtures import page_utils
|
|
start_page = option.split("--url=")[1]
|
|
if not page_utils.is_valid_url(start_page):
|
|
if page_utils.is_valid_url("https://" + start_page):
|
|
start_page = "https://" + start_page
|
|
else:
|
|
raise Exception("Invalid URL: %s" % start_page)
|
|
basic = True
|
|
elif option == "-b" or option == "--basic":
|
|
basic = True
|
|
elif option == "-r" or option == "--rec":
|
|
recorder = True
|
|
elif option == "--record" or option == "--recorder":
|
|
recorder = True
|
|
elif use_uc:
|
|
# UC must use English & ContextManager formats
|
|
continue
|
|
elif option == "--en" or option == "--english":
|
|
language = "English"
|
|
elif option == "--zh" or option == "--chinese":
|
|
language = "Chinese"
|
|
elif option == "--nl" or option == "--dutch":
|
|
language = "Dutch"
|
|
elif option == "--fr" or option == "--french":
|
|
language = "French"
|
|
elif option == "--it" or option == "--italian":
|
|
language = "Italian"
|
|
elif option == "--ja" or option == "--japanese":
|
|
language = "Japanese"
|
|
elif option == "--ko" or option == "--korean":
|
|
language = "Korean"
|
|
elif option == "--pt" or option == "--portuguese":
|
|
language = "Portuguese"
|
|
elif option == "--ru" or option == "--russian":
|
|
language = "Russian"
|
|
elif option == "--es" or option == "--spanish":
|
|
language = "Spanish"
|
|
elif option == "--bc" or option == "--basecase":
|
|
syntax = "BaseCase"
|
|
elif option == "--pf" or option == "--pytest-fixture":
|
|
syntax = "PytestFixture"
|
|
elif option == "--cf" or option == "--class-fixture":
|
|
syntax = "ClassFixture"
|
|
elif option == "--cm" or option == "--context-manager":
|
|
syntax = "ContextManager"
|
|
elif option == "--dc" or option == "--driver-context":
|
|
syntax = "DriverContext"
|
|
elif option == "--dm" or option == "--driver-manager":
|
|
syntax = "DriverManager"
|
|
elif option == "--uc":
|
|
basic = True
|
|
language = "English"
|
|
syntax = "ContextManager"
|
|
use_uc = True
|
|
else:
|
|
invalid_cmd = "\n===> INVALID OPTION: >> %s <<\n" % option
|
|
invalid_cmd = invalid_cmd.replace(">> ", ">>" + c5 + " ")
|
|
invalid_cmd = invalid_cmd.replace(" <<", " " + cr + "<<")
|
|
invalid_cmd = invalid_cmd.replace(">>", c7 + ">>" + cr)
|
|
invalid_cmd = invalid_cmd.replace("<<", c7 + "<<" + cr)
|
|
help_me = True
|
|
break
|
|
if help_me:
|
|
invalid_run_command(invalid_cmd)
|
|
|
|
dir_name = os.getcwd()
|
|
file_path = "%s/%s" % (dir_name, file_name)
|
|
|
|
body = "body"
|
|
para1 = "html body > p"
|
|
para2 = "p"
|
|
hello = "Hello"
|
|
goodbye = "Goodbye"
|
|
class_name = "MyTestClass"
|
|
if language == "Chinese":
|
|
hello = "你好"
|
|
goodbye = "再见"
|
|
class_name = "我的测试类"
|
|
elif language == "Dutch":
|
|
hello = "Hallo"
|
|
goodbye = "Dag"
|
|
class_name = "MijnTestklasse"
|
|
elif language == "French":
|
|
hello = "Bonjour"
|
|
goodbye = "Au revoir"
|
|
class_name = "MaClasseDeTest"
|
|
elif language == "Italian":
|
|
hello = "Ciao"
|
|
goodbye = "Addio"
|
|
class_name = "MiaClasseDiTest"
|
|
elif language == "Japanese":
|
|
hello = "こんにちは"
|
|
goodbye = "さようなら"
|
|
class_name = "私のテストクラス"
|
|
elif language == "Korean":
|
|
hello = "여보세요"
|
|
goodbye = "안녕"
|
|
class_name = "테스트_클래스"
|
|
elif language == "Portuguese":
|
|
hello = "Olá"
|
|
goodbye = "Tchau"
|
|
class_name = "MinhaClasseDeTeste"
|
|
elif language == "Russian":
|
|
hello = "Привет"
|
|
goodbye = "До свидания"
|
|
class_name = "МойТестовыйКласс"
|
|
elif language == "Spanish":
|
|
hello = "Hola"
|
|
goodbye = "Adiós"
|
|
class_name = "MiClaseDePrueba"
|
|
url = ""
|
|
if start_page:
|
|
url = start_page
|
|
elif basic:
|
|
url = "about:blank"
|
|
elif language not in ["English", "Dutch", "French", "Italian"]:
|
|
url = "data:text/html,<meta charset='utf-8'><p>%s<br><input>" % hello
|
|
else:
|
|
url = "data:text/html,<p>%s<br><input>" % hello
|
|
|
|
import_line = "from seleniumbase import BaseCase"
|
|
main_line = "BaseCase.main(__name__, __file__)"
|
|
parent_class = "BaseCase"
|
|
if language != "English":
|
|
from seleniumbase.translate.master_dict import MD_F
|
|
|
|
import_line = MD_F.get_import_line(language)
|
|
parent_class = MD_F.get_lang_parent_class(language)
|
|
class_line = "class %s(%s):" % (class_name, parent_class)
|
|
|
|
data = []
|
|
data.append("%s" % import_line)
|
|
if not recorder:
|
|
data.append(main_line)
|
|
data.append("")
|
|
data.append("")
|
|
data.append("%s" % class_line)
|
|
data.append(" def test_base(self):")
|
|
if not recorder:
|
|
data.append(' self.open("%s")' % url)
|
|
else:
|
|
data.append(" if self.recorder_ext and not self.xvfb:")
|
|
data.append(" import pdb; pdb.set_trace()")
|
|
if not basic and not recorder:
|
|
data.append(
|
|
' self.type("input", "%s")' " # selector, text" % goodbye
|
|
)
|
|
data.append(' self.click("%s") # selector' % para1)
|
|
data.append(' self.assert_element("%s") # selector' % body)
|
|
data.append(
|
|
' self.assert_text("%s", "%s")'
|
|
" # text, selector" % (hello, para2)
|
|
)
|
|
data.append("")
|
|
|
|
new_data = []
|
|
if language == "English" and syntax == "BaseCase":
|
|
new_data = data
|
|
elif language == "English" and syntax == "PytestFixture":
|
|
data = []
|
|
data.append("def test_base(sb):")
|
|
data.append(' sb.open("data:text/html,<p>Hello<br><input>")')
|
|
if not basic:
|
|
data.append(' sb.type("input", "Goodbye") # selector, text')
|
|
data.append(' sb.click("html body > p") # selector')
|
|
data.append(' sb.assert_element("body") # selector')
|
|
data.append(' sb.assert_text("Hello", "p") # text, selector')
|
|
data.append("")
|
|
new_data = data
|
|
elif language == "English" and syntax == "ClassFixture":
|
|
data = []
|
|
data.append("class %s:" % class_name)
|
|
data.append(" def test_base(self, sb):")
|
|
data.append(' sb.open("data:text/html,<p>Hello<br><input>")')
|
|
if not basic:
|
|
data.append(
|
|
' sb.type("input", "Goodbye") # selector, text'
|
|
)
|
|
data.append(' sb.click("html body > p") # selector')
|
|
data.append(' sb.assert_element("body") # selector')
|
|
data.append(
|
|
' sb.assert_text("Hello", "p") # text, selector'
|
|
)
|
|
data.append("")
|
|
new_data = data
|
|
elif language == "English" and syntax == "ContextManager":
|
|
data = []
|
|
data.append("from seleniumbase import SB")
|
|
data.append("")
|
|
if use_uc:
|
|
data.append('with SB(uc=True) as sb:')
|
|
else:
|
|
data.append('with SB(browser="chrome") as sb:')
|
|
if use_uc:
|
|
data.append(' url = "%s"' % url)
|
|
data.append(" sb.uc_open_with_reconnect(url, 4)")
|
|
data.append(" sb.uc_gui_click_captcha()")
|
|
else:
|
|
data.append(' sb.open("%s")' % url)
|
|
if not basic:
|
|
data.append(' sb.type("input", "Goodbye") # selector, text')
|
|
data.append(' sb.click("html body > p") # selector')
|
|
data.append(' sb.assert_element("input") # selector')
|
|
data.append(' sb.assert_text("Hello", "p") # text, selector')
|
|
data.append(' sb.highlight("p") # selector')
|
|
data.append(" sb.sleep(0.5) # seconds")
|
|
data.append("")
|
|
new_data = data
|
|
elif language == "English" and syntax == "DriverContext":
|
|
data = []
|
|
data.append("from seleniumbase import DriverContext")
|
|
data.append("")
|
|
data.append('with DriverContext(browser="chrome") as driver:')
|
|
data.append(' driver.get("%s")' % url)
|
|
if not basic:
|
|
data.append(' driver.type("input", "Goodbye") # sel, text')
|
|
data.append(' driver.click("html body > p") # selector')
|
|
data.append(' driver.assert_element("input") # selector')
|
|
data.append(' driver.assert_text("Hello", "p") # text, sel')
|
|
data.append(' driver.highlight("p") # selector')
|
|
data.append(" driver.sleep(0.5) # seconds")
|
|
data.append("")
|
|
new_data = data
|
|
elif language == "English" and syntax == "DriverManager":
|
|
data = []
|
|
data.append("from seleniumbase import Driver")
|
|
data.append("")
|
|
data.append('driver = Driver(browser="chrome")')
|
|
data.append("try:")
|
|
data.append(' driver.get("%s")' % url)
|
|
if not basic:
|
|
data.append(' driver.type("input", "Goodbye") # sel, text')
|
|
data.append(' driver.click("html body > p") # selector')
|
|
data.append(' driver.assert_element("input") # selector')
|
|
data.append(' driver.assert_text("Hello", "p") # text, sel')
|
|
data.append(' driver.highlight("p") # selector')
|
|
data.append(" driver.sleep(0.5) # seconds")
|
|
data.append("finally:")
|
|
data.append(" driver.quit()")
|
|
data.append("")
|
|
new_data = data
|
|
else:
|
|
from seleniumbase.translate.master_dict import MD
|
|
from seleniumbase.translate.master_dict import MD_L_Codes
|
|
|
|
md = MD.md
|
|
lang_codes = MD_L_Codes.lang
|
|
nl_code = lang_codes[language]
|
|
dl_code = lang_codes["English"]
|
|
for line in data:
|
|
found_swap = False
|
|
replace_count = line.count("self.") # Total possible replacements
|
|
for key in md.keys():
|
|
original = "self." + md[key][dl_code] + "("
|
|
if original in line:
|
|
replacement = "self." + md[key][nl_code] + "("
|
|
new_line = line.replace(original, replacement)
|
|
found_swap = True
|
|
replace_count -= 1
|
|
if replace_count == 0:
|
|
break # Done making replacements
|
|
else:
|
|
# There might be another method to replace in the line.
|
|
# Example: self.assert_true("Name" in self.get_title())
|
|
line = new_line
|
|
continue
|
|
if main_line in line:
|
|
new_main = "%s.main(__name__, __file__)" % parent_class
|
|
new_line = line.replace(main_line, new_main)
|
|
found_swap = True
|
|
if found_swap:
|
|
if new_line.endswith(" # noqa"): # Remove flake8 skip
|
|
new_line = new_line[0 : -len(" # noqa")]
|
|
new_data.append(new_line)
|
|
continue
|
|
new_data.append(line)
|
|
data = new_data
|
|
file = codecs.open(file_path, "w+", "utf-8")
|
|
file.writelines("\r\n".join(data))
|
|
file.close()
|
|
if " " not in file_name:
|
|
os.system("sbase print %s -n" % file_name)
|
|
elif '"' not in file_name:
|
|
os.system('sbase print "%s" -n' % file_name)
|
|
else:
|
|
os.system("sbase print '%s' -n" % file_name)
|
|
success = (
|
|
"\n" + c1 + '* Test file: "' + file_name + '" was created! *'
|
|
"" + cr + "\n"
|
|
)
|
|
print(success)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
invalid_run_command()
|