• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gocept / gocept.selenium / 6444675817

05 Oct 2023 09:33AM UTC coverage: 77.82%. Remained the same
6444675817

push

github

web-flow
Fix path

284 of 370 branches covered (0.0%)

Branch coverage included in aggregate %.

951 of 1217 relevant lines covered (78.14%)

3.87 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.05
/src/gocept/selenium/scripts/converthtmltests.py
1
#!/usr/bin/env python
2
"""
5✔
3
Convert HTML selenium tests to gocept.selenium.seleniumrcd test cases.
4
"""
5

6
from optparse import OptionParser
5✔
7
from string import Template
5✔
8
from xml.etree import ElementTree as HTMLTreeBuilder
5✔
9
from xml.etree.ElementTree import QName
5✔
10
import glob
5✔
11
import os
5✔
12
import re
5✔
13

14

15
module_template = Template('''\
5✔
16
# -*- coding: $encoding -*-
17
import unittest
18

19
import gocept.selenium.plonetesting
20
import $layer_module
21

22

23
class TestAll(gocept.selenium.plonetesting.TestCase):
24

25
    layer = $layer
26

27
$methods
28

29
def test_suite():
30
    return unittest.makeSuite(TestAll)
31
''')
32

33
variable_regexp = re.compile(r'\$\{(?P<varname>\w*)\}')
5✔
34
encoding_regexp = re.compile(r'charset=(.*)$')
5✔
35

36
method_template = Template('''\
5✔
37
    def test_$testname(self):
38
        selenium = self.selenium
39
$commands
40
''')
41

42

43
def formatcommand(command, *args):
5✔
44
    if not command:
5✔
45
        return ''
5✔
46

47
    arguments = []
5✔
48
    for arg in args:
5✔
49
        if not arg:
5✔
50
            continue
5✔
51
        matched = variable_regexp.match(arg)
5✔
52
        if matched is None:
5!
53
            arguments.append('"%s"' % arg)
5✔
54
        # XXX selenese should implement storeText
55
        # else:
56
        #    arguments.append("self.getVar('%s')" % matched.group('varname'))
57
    return '        selenium.{}({})'.format(command, ', '.join(arguments))
5✔
58

59

60
def make_parser():
5✔
61
    parser = OptionParser(
5✔
62
        usage="converthtmltests -l LAYER [options] directory",
63
        version="%prog 1.0")
64
    parser.add_option("-f", "--file", dest="target",
5✔
65
                      default=DEFAULT_TARGET,
66
                      help="write tests to FILE", metavar="FILE")
67
    parser.add_option("-l", "--layer", dest="layer", default=None,
5✔
68
                      help="full python import path to layer instance",
69
                      metavar="LAYER")
70
    parser.add_option("-v", "--verbose",
5✔
71
                      action="store_true", dest="verbose",
72
                      help="print progress messages to stdout")
73
    parser.add_option("-q", "--quiet",
5✔
74
                      action="store_false", dest="verbose", default=True,
75
                      help="do not print progress messages to stdout")
76
    return parser
5✔
77

78

79
DEFAULT_TARGET = 'tests_all_selenium.py'
5✔
80
LAYER_REQUIRED = 'Layer (-l) argument is required.'
5✔
81
DIRECTORY_REQUIRED = 'Source directory is required.'
5✔
82
LAYER_WITH_MODULE = 'Layer (-l) should include a module.'
5✔
83
ONE_DIRECTORY = 'Only one source directory should be provided.'
5✔
84
DIRECTORY_NOT_EXIST = 'Source directory does not exist.'
5✔
85
XHTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'
5✔
86

87

88
def parse_options(parser, args=None):
5✔
89
    directory = ''
5✔
90
    options, args = parser.parse_args(args=args)
5✔
91
    if not options.layer:
5✔
92
        parser.error(LAYER_REQUIRED)
5✔
93
    elif not args:
5✔
94
        parser.error(DIRECTORY_REQUIRED)
5✔
95
    elif len(options.layer.split('.')) <= 1:
5✔
96
        parser.error(LAYER_WITH_MODULE)
5✔
97
    elif len(args) > 1:
5✔
98
        parser.error(ONE_DIRECTORY)
5✔
99
    else:
100
        directory = os.path.abspath(args[0])
5✔
101
        if not os.path.exists(directory):
5✔
102
            parser.error(DIRECTORY_NOT_EXIST)
5✔
103
    return options, directory
5✔
104

105

106
def parse_directory(directory, verbose):
5✔
107
    pattern = os.path.join(directory, '*.html')
5✔
108
    prev_encoding = encoding = None
5✔
109
    for filename in glob.glob(pattern):
5✔
110
        if verbose:
5✔
111
            print("Parsing [%s]" % filename)
5✔
112
        filename = os.path.abspath(filename)
5✔
113
        testname, commands, encoding = parse_file(filename)
5✔
114
        if encoding and prev_encoding is None:
5✔
115
            prev_encoding = encoding
5✔
116
            yield encoding
5✔
117
        # XXX raise an error, if prev_encoding and encoding don't match
118
        if testname is None or len(commands) == 0:
5✔
119
            continue
5✔
120
        method = method_template.substitute(dict(
5✔
121
            testname=testname,
122
            commands='\n'.join(commands)))
123
        yield method
5✔
124

125

126
def parse_file(filename):
5✔
127
    tree = HTMLTreeBuilder.parse(filename)
5✔
128

129
    try:
5✔
130
        testname = tree.find('.//%s' % QName(XHTML_NAMESPACE, 'title')).text
5✔
131
    except AttributeError:
5✔
132
        return None, None, None
5✔
133
    content_type = tree.find(".//%s" % QName(
5✔
134
        XHTML_NAMESPACE, "meta[@http-equiv='Content-Type']")).get('content')
135
    matched = encoding_regexp.search(content_type)
5✔
136
    if matched is not None:
5!
137
        encoding = matched.group(1).lower()
5✔
138
    else:
139
        encoding = 'utf-8'
×
140
    commands = []
5✔
141
    for row in tree.findall('.//{}/{}'.format(QName(XHTML_NAMESPACE, 'tbody'),
5✔
142
                                              QName(XHTML_NAMESPACE, 'tr'))):
143
        command = formatcommand(
5✔
144
            *[td.text
145
              for td in row.findall(str(QName(XHTML_NAMESPACE, 'td')))])
146
        commands.append(command)
5✔
147
    return testname, commands, encoding
5✔
148

149

150
def make_module(methods, layer, layer_module, encoding):
5✔
151
    return module_template.substitute(dict(
5✔
152
        testname='all',
153
        encoding=encoding,
154
        methods='\n'.join(methods),
155
        layer=layer,
156
        layer_module=layer_module,
157
    ))
158

159

160
def main(args=None):
5✔
161
    parser = make_parser()
5✔
162
    options, directory = parse_options(parser, args)
5✔
163
    verbose = options.verbose
5✔
164
    target = os.path.abspath(options.target)
5✔
165
    layer = options.layer
5✔
166
    layer_module = ".".join(layer.split('.')[:-1])
5✔
167

168
    methods = [method for method in parse_directory(directory, verbose)]
5✔
169
    if methods:
5✔
170
        encoding = methods.pop(0)
5✔
171
    else:
172
        encoding = 'utf-8'
5✔
173

174
    if len(methods) == 0:
5✔
175
        print("No file was generated !")
5✔
176
        return
5✔
177
    if options.verbose:
5!
178
        print("Generating [%s]" % target)
5✔
179
    f = open(target, 'wb')
5✔
180
    module = make_module(methods, layer, layer_module, encoding)
5✔
181
    module = module.encode(encoding)
5✔
182
    f.write(module)
5✔
183
    f.close()
5✔
184

185

186
if __name__ == '__main__':
5!
187
    main()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc