Robot Framework
keywordremover.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 from robot.errors import DataError
17 from robot.model import SuiteVisitor, TagPattern
18 from robot.utils import Matcher, plural_or_not
19 
20 
21 def KeywordRemover(how):
22  upper = how.upper()
23  if upper.startswith('NAME:'):
24  return ByNameKeywordRemover(pattern=how[5:])
25  if upper.startswith('TAG:'):
26  return ByTagKeywordRemover(pattern=how[4:])
27  try:
28  return {'ALL': AllKeywordsRemover,
29  'PASSED': PassedKeywordRemover,
30  'FOR': ForLoopItemsRemover,
31  'WHILE': WhileLoopItemsRemover,
32  'WUKS': WaitUntilKeywordSucceedsRemover}[upper]()
33  except KeyError:
34  raise DataError(f"Expected 'ALL', 'PASSED', 'NAME:<pattern>', 'TAG:<pattern>', "
35  f"'FOR' or 'WUKS', got '{how}'.")
36 
37 
39 
42  _message = 'Keyword data removed using --RemoveKeywords option.'
43 
44  def __init__(self):
45  self._removal_message_removal_message = RemovalMessage(self._message_message)
46 
47  def _clear_content(self, item):
48  item.body.clear()
49  self._removal_message_removal_message.set(item)
50 
51  def _failed_or_warning_or_error(self, item):
52  return not item.passed or self._warning_or_error_warning_or_error(item)
53 
54  def _warning_or_error(self, item):
55  finder = WarningAndErrorFinder()
56  item.visit(finder)
57  return finder.found
58 
59 
61 
62  def visit_keyword(self, keyword):
63  self._clear_content_clear_content(keyword)
64 
65  def visit_for(self, for_):
66  self._clear_content_clear_content(for_)
67 
68  def visit_if_branch(self, branch):
69  self._clear_content_clear_content(branch)
70 
71 
73 
74  def start_suite(self, suite):
75  if not suite.statistics.failed:
76  for keyword in suite.setup, suite.teardown:
77  if not self._warning_or_error_warning_or_error(keyword):
78  self._clear_content_clear_content(keyword)
79 
80  def visit_test(self, test):
81  if not self._failed_or_warning_or_error_failed_or_warning_or_error(test):
82  for keyword in test.body:
83  self._clear_content_clear_content(keyword)
84 
85  def visit_keyword(self, keyword):
86  pass
87 
88 
89 class ByNameKeywordRemover(_KeywordRemover):
90 
91  def __init__(self, pattern):
92  _KeywordRemover.__init__(self)
93  self._matcher_matcher = Matcher(pattern, ignore='_')
94 
95  def start_keyword(self, kw):
96  if self._matcher_matcher.match(kw.name) and not self._warning_or_error_warning_or_error(kw):
97  self._clear_content_clear_content(kw)
98 
99 
101 
102  def __init__(self, pattern):
103  _KeywordRemover.__init__(self)
104  self._pattern_pattern = TagPattern(pattern)
105 
106  def start_keyword(self, kw):
107  if self._pattern_pattern.match(kw.tags) and not self._warning_or_error_warning_or_error(kw):
108  self._clear_content_clear_content(kw)
109 
110 
112 
115  _message = '%d passing step%s removed using --RemoveKeywords option.'
116 
117  def _remove_from_loop(self, loop):
118  before = len(loop.body)
119  self._remove_keywords_remove_keywords(loop.body)
120  self._removal_message_removal_message.set_if_removed(loop, before)
121 
122  def _remove_keywords(self, body):
123  iterations = body.filter(messages=False)
124  for it in iterations[:-1]:
125  if not self._failed_or_warning_or_error_failed_or_warning_or_error(it):
126  body.remove(it)
127 
128 
130 
131  def start_for(self, for_):
132  self._remove_from_loop_remove_from_loop(for_)
133 
134 
136 
137  def start_while(self, while_):
138  self._remove_from_loop_remove_from_loop(while_)
139 
140 
142 
145  _message = '%d failing step%s removed using --RemoveKeywords option.'
146 
147  def start_keyword(self, kw):
148  if kw.libname == 'BuiltIn' and kw.kwname == 'Wait Until Keyword Succeeds':
149  before = len(kw.body)
150  self._remove_keywords_remove_keywords(kw.body)
151  self._removal_message_removal_message.set_if_removed(kw, before)
152 
153  def _remove_keywords(self, body):
154  keywords = body.filter(messages=False)
155  if keywords:
156  include_from_end = 2 if keywords[-1].passed else 1
157  for kw in keywords[:-include_from_end]:
158  if not self._warning_or_error_warning_or_error(kw):
159  body.remove(kw)
160 
161 
163 
164  def __init__(self):
165  self.foundfound = False
166 
167  def start_suite(self, suite):
168  return not self.foundfound
169 
170  def start_test(self, test):
171  return not self.foundfound
172 
173  def start_keyword(self, keyword):
174  return not self.foundfound
175 
176  def visit_message(self, msg):
177  if msg.level in ('WARN', 'ERROR'):
178  self.foundfound = True
179 
180 
182 
183  def __init__(self, message):
184  self._message_message = message
185 
186  def set_if_removed(self, kw, len_before):
187  removed = len_before - len(kw.body)
188  if removed:
189  self.setset(kw, self._message_message % (removed, plural_or_not(removed)))
190 
191  def set(self, kw, message=None):
192  kw.doc = ('%s\n\n_%s_' % (kw.doc, message or self._message_message)).strip()
Interface to ease traversing through a test suite structure.
Definition: visitor.py:85
def visit_keyword(self, keyword)
Implements traversing through keywords.
def visit_for(self, for_)
Implements traversing through FOR loops.
def visit_if_branch(self, branch)
Implements traversing through single IF/ELSE branch.
def start_keyword(self, kw)
Called when a keyword starts.
def start_keyword(self, kw)
Called when a keyword starts.
def start_for(self, for_)
Called when a FOR loop starts.
def visit_test(self, test)
Implements traversing through tests.
def start_suite(self, suite)
Called when a suite starts.
def visit_keyword(self, keyword)
Implements traversing through keywords.
def set_if_removed(self, kw, len_before)
def start_keyword(self, kw)
Called when a keyword starts.
def start_keyword(self, keyword)
Called when a keyword starts.
def visit_message(self, msg)
Implements visiting messages.
def start_suite(self, suite)
Called when a suite starts.
def start_test(self, test)
Called when a test starts.
def start_while(self, while_)
Called when a WHILE loop starts.
def TagPattern(pattern)
Definition: tags.py:116
def plural_or_not(item)
Definition: misc.py:73