5 new revisions:
Revision: fa5b18ab3019
Branch: default
Author: Pekka Klärck
Date: Tue Sep 18 03:39:32 2012
Log: XML lib: better comment
http://code.google.com/p/robotframework/source/detail?r=fa5b18ab3019
Revision: 1e3d3721355c
Branch: default
Author: Pekka Klärck
Date: Tue Sep 18 03:50:53 2012
Log: Cleaned up XML lib atests a little
http://code.google.com/p/robotframework/source/detail?r=1e3d3721355c
Revision: 724b78afc55d
Branch: default
Author: Pekka Klärck
Date: Tue Sep 18 07:49:18 2012
Log: argumentparser: don't decode argument files read from stdin w/
ipy. ap...
http://code.google.com/p/robotframework/source/detail?r=724b78afc55d
Revision: aa50db8fa71c
Branch: default
Author: Pekka Klärck
Date: Tue Sep 18 08:16:36 2012
Log: XML lib: Element Should (Not) Exist keywords...
http://code.google.com/p/robotframework/source/detail?r=aa50db8fa71c
Revision: 9dbeaa4778bb
Branch: default
Author: Pekka Klärck
Date: Tue Sep 18 08:20:11 2012
Log: XML lib: Add Element and Remove Element(s) keywords....
http://code.google.com/p/robotframework/source/detail?r=9dbeaa4778bb
==============================================================================
Revision: fa5b18ab3019
Branch: default
Author: Pekka Klärck
Date: Tue Sep 18 03:39:32 2012
Log: XML lib: better comment
http://code.google.com/p/robotframework/source/detail?r=fa5b18ab3019
Modified:
/src/robot/libraries/XML.py
=======================================
--- /src/robot/libraries/XML.py Tue Sep 18 03:15:00 2012
+++ /src/robot/libraries/XML.py Tue Sep 18 03:39:32 2012
@@ -702,7 +702,8 @@
def save_xml(self, source, path, encoding='UTF-8'):
tree = ET.ElementTree(self.get_element(source))
kwargs = {'xml_declaration': True} if ET.VERSION >= '1.3' else {}
- # Older ET versions don't close files they open.
+ # Need to explicitly open/close files because older ET versions
don't
+ # close files they open and Jython/IPY don't close them implicitly.
with open(path, 'w') as output:
tree.write(output, encoding, **kwargs)
==============================================================================
Revision: 1e3d3721355c
Branch: default
Author: Pekka Klärck
Date: Tue Sep 18 03:50:53 2012
Log: Cleaned up XML lib atests a little
http://code.google.com/p/robotframework/source/detail?r=1e3d3721355c
Modified:
/atest/testdata/standard_libraries/xml/resource.txt
/atest/testdata/standard_libraries/xml/save_xml.txt
/atest/testdata/standard_libraries/xml/set_element_information.txt
=======================================
--- /atest/testdata/standard_libraries/xml/resource.txt Wed Jun 27 06:08:32
2012
+++ /atest/testdata/standard_libraries/xml/resource.txt Tue Sep 18 03:50:53
2012
@@ -3,3 +3,11 @@
*** Variables ***
${TEST} = ${CURDIR}/test.xml
+${SIMPLE} = <root><child id="1">text</child></root>
+
+
+*** Keywords ***
+Parse XML To Test Variable
+ [Arguments] ${input} ${var}
+ ${result} = Parse XML ${input}
+ Set Test Variable ${var} ${result}
=======================================
--- /atest/testdata/standard_libraries/xml/save_xml.txt Tue Sep 18 01:21:55
2012
+++ /atest/testdata/standard_libraries/xml/save_xml.txt Tue Sep 18 03:50:53
2012
@@ -5,7 +5,6 @@
*** Variables ***
${OUTPUT} %{TEMPDIR}/xmllib.xml
-${SIMPLE} <root><child a="1" /><child>text</child></root>
${NON-ASCII} <hyvää>yötä</hyvää>
*** Test Cases ***
=======================================
--- /atest/testdata/standard_libraries/xml/set_element_information.txt Tue
Sep 18 02:08:30 2012
+++ /atest/testdata/standard_libraries/xml/set_element_information.txt Tue
Sep 18 03:50:53 2012
@@ -1,9 +1,6 @@
*** Settings ***
Resource resource.txt
-Test Setup Parse Simple XML
-
-*** Variables ***
-${SIMPLE} <root><child id="1">text</child></root>
+Test Setup Parse XML To Test Variable ${SIMPLE} \${XML}
*** Test Cases ***
@@ -55,8 +52,3 @@
${attrib} = Get Element Attributes ${XML} xpath=child
Should Be Empty ${attrib}
-
-*** Keywords ***
-Parse Simple XML
- ${XML} = Parse XML ${SIMPLE}
- Set Test Variable ${XML}
==============================================================================
Revision: 724b78afc55d
Branch: default
Author: Pekka Klärck
Date: Tue Sep 18 07:49:18 2012
Log: argumentparser: don't decode argument files read from stdin w/
ipy. apparently content is already in correct encoding.
http://code.google.com/p/robotframework/source/detail?r=724b78afc55d
Modified:
/src/robot/utils/argumentparser.py
=======================================
--- /src/robot/utils/argumentparser.py Thu Aug 30 03:53:56 2012
+++ /src/robot/utils/argumentparser.py Tue Sep 18 07:49:18 2012
@@ -200,7 +200,7 @@
if path.upper() != 'STDIN':
content = self._read_argfile(path)
else:
- content = decode_output(sys.__stdin__.read())
+ content = self._read_argfile_from_stdin()
return self._process_argfile(content)
def _read_argfile(self, path):
@@ -214,6 +214,12 @@
content = content[1:]
return content
+ def _read_argfile_from_stdin(self):
+ content = sys.__stdin__.read()
+ if sys.platform != 'cli':
+ content = decode_output(content)
+ return content
+
def _process_argfile(self, content):
args = []
for line in content.splitlines():
==============================================================================
Revision: aa50db8fa71c
Branch: default
Author: Pekka Klärck
Date: Tue Sep 18 08:16:36 2012
Log: XML lib: Element Should (Not) Exist keywords
Update issue 1236
Status: Started
Implemented and tested. Docs missing.
Implementing both of these was easy. The hard part was deciding how Element
Should Exist should behave if there is more than one match. Get Element
fails in that case so it would have been logical to behave the same way. I
didn't, however, want to implement separate Elements Should Exist keyword
so decided that more than one match is accepted.
It would be possible to implement additional Element Count Should Be
keyword for matching element counts more precisely. Not sure is that worth
the effort since this isn't likely to be that common use case, and you can
pretty easily verify counts using first Get Elements and then e.g. Length
Should Be from BuiltIn.
Element Should Not Exist was the most important keyword to add anyway.
http://code.google.com/p/robotframework/source/detail?r=aa50db8fa71c
Added:
/atest/robot/standard_libraries/xml/element_should_exist.txt
/atest/testdata/standard_libraries/xml/element_should_exist.txt
Modified:
/src/robot/libraries/XML.py
=======================================
--- /dev/null
+++ /atest/robot/standard_libraries/xml/element_should_exist.txt Tue Sep 18
08:16:36 2012
@@ -0,0 +1,27 @@
+*** Settings ***
+Suite Setup Run Tests ${EMPTY}
standard_libraries/xml/element_should_exist.txt
+Force Tags regression pybot jybot
+Resource atest_resource.txt
+
+*** Test Cases ***
+
+Element Should Exist Passes When There Are One Or More Matches
+ Check Test Case ${TESTNAME}
+
+Element Should Exist Fails When There Are No Matches
+ Check Test Case ${TESTNAME}
+
+Element Should Exist With Custom Error Message
+ Check Test Case ${TESTNAME}
+
+Element Should Not Exist Passes When There Are No Matches
+ Check Test Case ${TESTNAME}
+
+Element Should Not Exist Fails When There Is One Match
+ Check Test Case ${TESTNAME}
+
+Element Should Not Exist Fails When There Are Multiple Matches
+ Check Test Case ${TESTNAME}
+
+Element Should Not Exist With Custom Error Message
+ Check Test Case ${TESTNAME}
=======================================
--- /dev/null
+++ /atest/testdata/standard_libraries/xml/element_should_exist.txt Tue Sep
18 08:16:36 2012
@@ -0,0 +1,33 @@
+*** Settings ***
+Resource resource.txt
+
+*** Test Cases ***
+Element Should Exist Passes When There Are One Or More Matches
+ Element Should Exist ${TEST} another/child
+ Element Should Exist ${TEST} xpath=child
+
+Element Should Exist Fails When There Are No Matches
+ [Documentation] FAIL No element matching 'nönëx' found.
+ Element Should Exist <root/> nönëx
+
+Element Should Exist With Custom Error Message
+ [Documentation] FAIL My error
+ Element Should Exist ${TEST} xpath=another/child message=Not
used
+ Element Should Exist <root/> nonex My error
+
+Element Should Not Exist Passes When There Are No Matches
+ Element Should Not Exist ${TEST} nonex
+ Element Should Not Exist <root/> xpath=child
+
+Element Should Not Exist Fails When There Is One Match
+ [Documentation] FAIL One element matching 'another/child' found.
+ Element Should Not Exist ${TEST} xpath=another/child
+
+Element Should Not Exist Fails When There Are Multiple Matches
+ [Documentation] FAIL Multiple elements (4) matching './/child'
found.
+ Element Should Not Exist ${TEST} xpath=.//child
+
+Element Should Not Exist With Custom Error Message
+ [Documentation] FAIL My error
+ Element Should Not Exist <root/> nonex Not used
+ Element Should Not Exist ${TEST} xpath=another/child
message=My error
=======================================
--- /src/robot/libraries/XML.py Tue Sep 18 03:39:32 2012
+++ /src/robot/libraries/XML.py Tue Sep 18 08:16:36 2012
@@ -284,6 +284,28 @@
with ETSource(source) as source:
return ET.parse(source).getroot()
+ def element_should_exist(self, source, xpath='.', message=None):
+ count = len(self.get_elements(source, xpath))
+ if not count:
+ self._raise_wrong_number_of_matches(count, xpath, message)
+
+ def element_should_not_exist(self, source, xpath='.', message=None):
+ count = len(self.get_elements(source, xpath))
+ if count:
+ self._raise_wrong_number_of_matches(count, xpath, message)
+
+ def _raise_wrong_number_of_matches(self, count, xpath, message=None):
+ if not message:
+ message = self._wrong_number_of_matches(count, xpath)
+ raise AssertionError(message)
+
+ def _wrong_number_of_matches(self, count, xpath):
+ if not count:
+ return "No element matching '%s' found." % xpath
+ if count == 1:
+ return "One element matching '%s' found." % xpath
+ return "Multiple elements (%d) matching '%s' found." % (count,
xpath)
+
def get_element(self, source, xpath='.'):
"""Returns an element in the `source` matching the `xpath`.
@@ -303,11 +325,8 @@
See also `Parse XML` and `Get Elements`.
"""
elements = self.get_elements(source, xpath)
- if not elements:
- raise RuntimeError("No element matching '%s' found." % xpath)
- if len(elements) > 1:
- raise RuntimeError("Multiple elements (%d) matching '%s'
found."
- % (len(elements), xpath))
+ if len(elements) != 1:
+ self._raise_wrong_number_of_matches(len(elements), xpath)
return elements[0]
def get_elements(self, source, xpath):
==============================================================================
Revision: 9dbeaa4778bb
Branch: default
Author: Pekka Klärck
Date: Tue Sep 18 08:20:11 2012
Log: XML lib: Add Element and Remove Element(s) keywords.
Update issue 1234
Status: Started
Implemented, and tested, following keywords. Also these are yet
un-documented.
Add Element
Remove Element
Remove Elements
The current set of new keywords might actually be enough for common XML
modifying needs. Need to review them and discuss with a customer.
http://code.google.com/p/robotframework/source/detail?r=9dbeaa4778bb
Added:
/atest/robot/standard_libraries/xml/add_and_remove_elements.txt
/atest/testdata/standard_libraries/xml/add_and_remove_elements.txt
Modified:
/atest/testdata/standard_libraries/xml/resource.txt
/src/robot/libraries/XML.py
=======================================
--- /dev/null
+++ /atest/robot/standard_libraries/xml/add_and_remove_elements.txt Tue Sep
18 08:20:11 2012
@@ -0,0 +1,48 @@
+*** Settings ***
+Suite Setup Run Tests ${EMPTY}
standard_libraries/xml/add_and_remove_elements.txt
+Force Tags regression pybot jybot
+Resource atest_resource.txt
+
+*** Test Cases ***
+
+Add Element
+ Check Test Case ${TESTNAME}
+
+Add Element As String
+ Check Test Case ${TESTNAME}
+
+Add Element With Index
+ Check Test Case ${TESTNAME}
+
+Remove Element
+ Check Test Case ${TESTNAME}
+
+Remove Non-Direct Child Element
+ Check Test Case ${TESTNAME}
+
+Remove Element Fails If No Element Match
+ Check Test Case ${TESTNAME}
+
+Remove Element Fails If Multiple Elements Match
+ Check Test Case ${TESTNAME}
+
+Remove Element Requires Xpath
+ Check Test Case ${TESTNAME}
+
+Remove Element Cannot Remove Root Element Fails
+ Check Test Case ${TESTNAME}
+
+Remove Elements
+ Check Test Case ${TESTNAME}
+
+Remove Elements Can Remove All Child Elements
+ Check Test Case ${TESTNAME}
+
+Remove Elements Does Not Fail If No Element Match
+ Check Test Case ${TESTNAME}
+
+Remove Elements Requires Xpath
+ Check Test Case ${TESTNAME}
+
+Remove Elements Cannot Remove Root Element Fails
+ Check Test Case ${TESTNAME}
=======================================
--- /dev/null
+++ /atest/testdata/standard_libraries/xml/add_and_remove_elements.txt Tue
Sep 18 08:20:11 2012
@@ -0,0 +1,71 @@
+*** Settings ***
+Resource resource.txt
+Test Setup Parse XML To Test Variable ${SIMPLE} \${XML}
+
+*** Variables ***
+${NEW} <new attr="value"/>
+
+*** Test Cases ***
+
+Add Element
+ ${elem} = Parse XML ${NEW}
+ Add Element ${XML} ${elem}
+ Element Attribute Should Be ${XML} attr value xpath=new
+ ${children} = Get Child Elements ${XML}
+ Should Be Equal ${children[-1].tag} new
+
+Add Element As String
+ Add Element ${XML} ${NEW} xpath=c2
+ Element Attribute Should Be ${XML} attr value xpath=c2/new
+
+Add Element With Index
+ Add Element ${XML} ${NEW} index=0
+ Element Attribute Should Be ${XML} attr value xpath=new
+ ${children} = Get Child Elements ${XML}
+ Should Be Equal ${children[0].tag} new
+
+Remove Element
+ Remove Element ${XML} child
+ Remove Element ${XML} xpath=c2
+ Elements Should Be Equal ${XML} <root/>
+
+Remove Non-Direct Child Element
+ Remove Element ${XML} c2/gc
+ Element Should Not Exist ${XML} c2/gc
+
+Remove Element Fails If No Element Match
+ [Documentation] FAIL No element matching 'nonex' found.
+ Remove Element ${XML} nonex
+
+Remove Element Fails If Multiple Elements Match
+ [Documentation] FAIL Multiple elements (3) matching 'child' found.
+ Remove Element ${TEST} child
+
+Remove Element Requires Xpath
+ [Documentation] FAIL No xpath given.
+ Remove Element ${XML}
+
+Remove Element Cannot Remove Root Element Fails
+ [Documentation] FAIL Cannot remove root element.
+ Remove Element ${XML} .
+
+Remove Elements
+ ${tree} = Parse XML ${TEST}
+ Remove Elements ${tree} xpath=.//child
+ Element Should Not Exist ${tree} .//child
+
+Remove Elements Can Remove All Child Elements
+ Remove Elements ${XML} *
+ Elements Should Be Equal ${XML} <root/>
+
+Remove Elements Does Not Fail If No Element Match
+ Remove Elements ${XML} nonex
+
+Remove Elements Requires Xpath
+ [Documentation] FAIL No xpath given.
+ Remove Elements ${XML}
+
+Remove Elements Cannot Remove Root Element Fails
+ [Documentation] FAIL Cannot remove root element.
+ Remove Elements ${XML} .
+
=======================================
--- /atest/testdata/standard_libraries/xml/resource.txt Tue Sep 18 03:50:53
2012
+++ /atest/testdata/standard_libraries/xml/resource.txt Tue Sep 18 08:20:11
2012
@@ -3,7 +3,7 @@
*** Variables ***
${TEST} = ${CURDIR}/test.xml
-${SIMPLE} = <root><child id="1">text</child></root>
+${SIMPLE} = <root><child id="1">text</child><c2><gc /></c2></root>
*** Keywords ***
=======================================
--- /src/robot/libraries/XML.py Tue Sep 18 08:16:36 2012
+++ /src/robot/libraries/XML.py Tue Sep 18 08:20:11 2012
@@ -718,6 +718,41 @@
def remove_element_attributes(self, source, xpath='.'):
self.get_element(source, xpath).attrib.clear()
+ def add_element(self, source, element, index=None, xpath='.'):
+ source = self.get_element(source, xpath)
+ element = self.get_element(element)
+ if index is None:
+ source.append(element)
+ else:
+ source.insert(int(index), element)
+
+ def remove_element(self, source, xpath=''):
+ self._verify_removing_xpath(xpath)
+ source = self.get_element(source)
+ self._remove_element(source, self.get_element(source, xpath))
+
+ def remove_elements(self, source, xpath=''):
+ self._verify_removing_xpath(xpath)
+ source = self.get_element(source)
+ for element in self.get_elements(source, xpath):
+ self._remove_element(source, element)
+
+ def _verify_removing_xpath(self, xpath):
+ if not xpath:
+ raise RuntimeError('No xpath given.')
+ if xpath == '.':
+ raise RuntimeError('Cannot remove root element.')
+
+ def _remove_element(self, tree, element):
+ parent = self._find_parent(tree, element)
+ parent.remove(element)
+
+ def _find_parent(self, tree, element):
+ for parent in tree.getiterator():
+ for child in parent:
+ if child is element:
+ return parent
+
def save_xml(self, source, path, encoding='UTF-8'):
tree = ET.ElementTree(self.get_element(source))
kwargs = {'xml_declaration': True} if ET.VERSION >= '1.3' else {}