I am trying to validate a pin code in my application. I am using Katalon and I have not been able to find an answer.
The pin code that I need to validate is the same length but different each time I run the test and looks like this on my page: PIN Code: 4938475948.
How can I account for the number changing each time I run the test?
I have tried the following regular expressions:
assertEquals(
"PIN Code: [^a-z ]*([.0-9])*\\d",
selenium.getText("//*[#id='RegItemContent0']/div/table/tbody/tr/td[2]/table/tbody/tr[2]/td/div[1]/div[3]/ul/li[2]/span")
);
Note: This was coded in Selenium and converted to Katalon.
In Katalon, use a combination of WebUI.getText() and WebUI.verifyMatch() to do the same thing.
E.g.
TestObject object = new TestObject().addProperty('xpath', ConditionType.EQUALS, '//*[#id='RegItemContent0']/div/table/tbody/tr/td[2]/table/tbody/tr[2]/td/div[1]/div[3]/ul/li[2]/span')
def actualText = WebUI.getText(object)
def expectedText = '4938475948'
WebUI.verifyMatch(actualText, expectedText, true)
Use also toInteger() or toString() groovy methods to convert types, if needed.
Editing upper example but to get this working
TestObject object = new TestObject().addProperty('xpath', ConditionType.EQUALS, '//*[#id='RegItemContent0']/div/table/tbody/tr/td[2]/table/tbody/tr[2]/td/div[1]/div[3]/ul/li[2]/span')
def actualText = WebUI.getText(object)
def expectedText = '4938475948'
WebUI.verifyMatch(actualText, expectedText, true)
This can be done as variable but in Your case I recommend using some java
import java.util.Random;
Random rand = new Random();
int n = rand.nextInt(9000000000) + 1000000000;
// this will also cover the bad PIN (above limit)
I'd tweak your regex just a little since your pin code is the same length each time: you could limit the number of digits that the regex looks for and make sure the following character is white space (i.e. not a digit, or another stray character). Lastly, use the "true" flag to let the WebUI.verifyMatch() know it should expect a regular expression from the second string (the regex must be the second parameter).
def regexExpectedText = "PIN Code: ([0-9]){10}\\s"
TestObject pinCodeTO = new TestObject().addProperty('xpath', ConditionType.EQUALS, '//*[#id='RegItemContent0']/div/table/tbody/tr/td[2]/table/tbody/tr[2]/td/div[1]/div[3]/ul/li[2]/span')
def actualText = WebUI.getText(pinCodeTO)
WebUI.verifyMatch(actualText, expectedText, true)
Hope that helps!
Related
I've got some code which uses StringSession to talk to the Telegram API using telethon.
In my unit tests, I'm trying to instantiate a mocked TelegramClient, passing it a StringSession(myvalue) object as the first parameter. The real code works fine, but I need a fake session string for 'myvalue', to use in my unit tests (where I have a mocked telegram client).
How can I create a dummy value for 'myvalue' which will successfully execute StringSession(myvalue)?
Currently, my tests are dying here:
self = <telethon.sessions.string.StringSession object at 0x7f0777492ad0>
string = 'dummyxxx'
def __init__(self, string: str = None):
super().__init__()
if string:
if string[0] != CURRENT_VERSION:
raise ValueError('Not a valid string')
string = string[1:]
ip_len = 4 if len(string) == 352 else 16
> self._dc_id, ip, self._port, key = struct.unpack(
_STRUCT_PREFORMAT.format(ip_len), StringSession.decode(string))
E struct.error: unpack requires a buffer of 275 bytes
If you don't need a valid session to start with, you can also use MemorySession instead:
from telethon.sessions import MemorySession
session = MemorySession()
# use session variable when creating the client
Someone posted an answer which helped point me in the right direction, but they later deleted it for some reason.
In case it helps anyone else, here is the code that worked for me:
import struct
import base64
from telethon.sessions import StringSession
_STRUCT_PREFORMAT = '>B{}sH256s'
CURRENT_VERSION = '1'
dc_id = 1
ip = b'\x7f\x00\x00\x01' # 127.0.0.1
port = 80
key = b'\x00' * 256
string = StringSession.encode(struct.pack(
_STRUCT_PREFORMAT.format(len(ip)),
dc_id,
ip,
port,
key
))
myvalue = CURRENT_VERSION + string
# Create the StringSession object using the dummy value to confirm it works
session = StringSession(myvalue)
print(myvalue)
I am trying to extract the content of the [Documentation] section as a string for comparision with other part in a Python script.
I was told to use Robot framework API https://robot-framework.readthedocs.io/en/stable/
to extract but I have no idea how.
However, I am required to work with version 3.1.2
Example:
*** Test Cases ***
ATC Verify that Sensor Battery can enable and disable manufacturing mode
[Documentation] E1: This is the description of the test 1
... E2: This is the description of the test 2
[Tags] E1 TRACE{Trace_of_E1}
... E2 TRACE{Trace_of_E2}
Extract the string as
E1: This is the description of the test 1
E2: This is the description of the test 2
Have a look at these examples. I did something similar to generate testplans descritio. I tried to adapt my code to your requirements and this could maybe work for you.
import os
import re
from robot.api.parsing import (
get_model, get_tokens, Documentation, EmptyLine, KeywordCall,
ModelVisitor, Token
)
class RobotParser(ModelVisitor):
def __init__(self):
# Create object with remarkup_text to store formated documentation
self.text = ''
def get_text(self):
return self.text
def visit_TestCase(self, node):
# The matched `TestCase` node is a block with `header` and
# `body` attributes. `header` is a statement with familiar
# `get_token` and `get_value` methods for getting certain
# tokens or their value.
for keyword in node.body:
# skip empty lines
if keyword.get_value(Token.DOCUMENTATION) == None:
continue
self.text += keyword.get_value(Token.ARGUMENT)
def visit_Documentation(self,node):
# The matched "Documentation" node with value
self.remarkup_text += node.value + self.new_line
def visit_File(self, node):
# Call `generic_visit` to visit also child nodes.
return self.generic_visit(node)
if __name__ == "__main__":
path = "../tests"
for filename in os.listdir(path):
if re.match(".*\.robot", filename):
model = get_model(os.path.join(path, filename))
robot_parser = RobotParser()
robot_parser.visit(model)
text=robot_parser._text()
The code marked as best answer didn't quite work for me and has a lot of redundancy but it inspired me enough to get into the parsing and write it in a much readable and efficient way that actually works as is. You just have to have your own way of generating & iterating through filesystem where you call the get_robot_metadata(filepath) function.
from robot.api.parsing import (get_model, ModelVisitor, Token)
class RobotParser(ModelVisitor):
def __init__(self):
self.testcases = {}
def visit_TestCase(self, node):
testcasename = (node.header.name)
self.testcases[testcasename] = {}
for section in node.body:
if section.get_value(Token.DOCUMENTATION) != None:
documentation = section.value
self.testcases[testcasename]['Documentation'] = documentation
elif section.get_value(Token.TAGS) != None:
tags = section.values
self.testcases[testcasename]['Tags'] = tags
def get_testcases(self):
return self.testcases
def get_robot_metadata(filepath):
if filepath.endswith('.robot'):
robot_parser = RobotParser()
model = get_model(filepath)
robot_parser.visit(model)
metadata = robot_parser.get_testcases()
return metadata
This function will be able to extract the [Documentation] section from the testcase:
def documentation_extractor(testcase):
documentation = []
for setting in testcase.settings:
if len(setting) > 2 and setting[1].lower() == "[documentation]":
for doc in setting[2:]:
if doc.startswith("#"):
# the start of a comment, so skip rest of the line
break
documentation.append(doc)
break
return "\n".join(documentation)
Looking for a way to return just the stdout string when using the sendline method from pxssh module. Here is an example of code.
import pxssh
s = pxssh.pxssh()
s.force_password = True
s.login('host', 'user', 'password')
s.prompt()
print(s.before)
I get a string with delimters returned. Is this avoidable? I'd like to skip the step of cleaning this up to a usable string with regex if possible.
>>> print(s.before)
b'uptime\r\n 11:53:28 up 14 days, 19:13, 1 user, load average: 0.22, 0.19, 0.17\r\n'
I think you just need to modify the string after you retrieve it.
print(s.before.replace("\r\n", ""))
I'm looking to create a group hierarchy automatically, by having some kind of Alias command. E.g. I want the groups
Extension Methods
String Extensions
Stream Extensions
...
to be created with doxygen comments such as
/** Documentation for the method
* \extension{string}
*/
public void ExtensionMethod(this string str){
...
}
Where \extension{string} would map to something like
\addtogroup stringExtensions string Extensions
\ingroup ExtnMethods
Unfortunately this means that all the documentation written for the method gets associated with the group instead.
The closest I've got is that if you have something like
/** \addtogroup stringExtensions string Extensions
* \ingroup ExtnMethods
* \#{
* \#}
*/
/** \ingroup stringExtensions
* Documentation for the method
*/
public void ExtensionMethod(this string str){
...
}
it would work, but this needs the 2 separate comment blocks and I can't find any way to do that using an Alias.
I know that something can probably be achieved with an inputfilter - but I'm hoping something far simpler can be achieved.
I've found an answer using inputfilters that was neater than I first supposed - parse the entire file looking for \extension{...}, replacing it with an appropriate \ingroup command, and then append the desired \addgroup commands at the bottom of the file.
This can then be run as an inputfilter
The following is a python script that does this. Note that it doesn't check that what it's replacing is actually within a doxygen comment, but it's good enough for my purposes.
#!python
import sys, re
if(len(sys.argv) != 2):
print "Need exactly one argument, the file to filter"
exit(1)
extnFinder = re.compile("\\\\extension{(\w+)}")
extnTypes = set();
filename = sys.argv[1]
fileIn = open(filename, "r")
line = fileIn.readline()
def extnSub(matchobj):
extnTypes.add(matchobj.group(1))
return "\ingroup %(extn)sExtensions" % {'extn':matchobj.group(1)}
while line:
matches = extnFinder.findall(line)
sys.stdout.write(re.sub(extnFinder,extnSub,line))
line = fileIn.readline()
for extn in extnTypes:
print "\n\n/**\\addtogroup %(extn)sExtensions %(extn)s Extensions\n\\ingroup ExtnMethods\n */\n" % {'extn':extn}
How do I get an outline view in sublime text editor for Windows?
The minimap is helpful but I miss a traditional outline (a klickable list of all the functions in my code in the order they appear for quick navigation and orientation)
Maybe there is a plugin, addon or similar? It would also be nice if you can shortly name which steps are neccesary to make it work.
There is a duplicate of this question on the sublime text forums.
Hit CTRL+R, or CMD+R for Mac, for the function list. This works in Sublime Text 1.3 or above.
A plugin named Outline is available in package control, try it!
https://packagecontrol.io/packages/Outline
Note: it does not work in multi rows/columns mode.
For multiple rows/columns work use this fork:
https://github.com/vlad-wonderkidstudio/SublimeOutline
I use the fold all action. It will minimize everything to the declaration, I can see all the methods/functions, and then expand the one I'm interested in.
I briefly look at SublimeText 3 api and view.find_by_selector(selector) seems to be able to return a list of regions.
So I guess that a plugin that would display the outline/structure of your file is possible.
A plugin that would display something like this:
Note: the function name display plugin could be used as an inspiration to extract the class/methods names or ClassHierarchy to extract the outline structure
If you want to be able to printout or save the outline the ctr / command + r is not very useful.
One can do a simple find all on the following grep ^[^\n]*function[^{]+{ or some variant of it to suit the language and situation you are working in.
Once you do the find all you can copy and paste the result to a new document and depending on the number of functions should not take long to tidy up.
The answer is far from perfect, particularly for cases when the comments have the word function (or it's equivalent) in them, but I do think it's a helpful answer.
With a very quick edit this is the result I got on what I'm working on now.
PathMaker.prototype.start = PathMaker.prototype.initiate = function(point){};
PathMaker.prototype.path = function(thePath){};
PathMaker.prototype.add = function(point){};
PathMaker.prototype.addPath = function(path){};
PathMaker.prototype.go = function(distance, angle){};
PathMaker.prototype.goE = function(distance, angle){};
PathMaker.prototype.turn = function(angle, distance){};
PathMaker.prototype.continue = function(distance, a){};
PathMaker.prototype.curve = function(angle, radiusX, radiusY){};
PathMaker.prototype.up = PathMaker.prototype.north = function(distance){};
PathMaker.prototype.down = PathMaker.prototype.south = function(distance){};
PathMaker.prototype.east = function(distance){};
PathMaker.prototype.west = function(distance){};
PathMaker.prototype.getAngle = function(point){};
PathMaker.prototype.toBezierPoints = function(PathMakerPoints, toSource){};
PathMaker.prototype.extremities = function(points){};
PathMaker.prototype.bounds = function(path){};
PathMaker.prototype.tangent = function(t, points){};
PathMaker.prototype.roundErrors = function(n, acurracy){};
PathMaker.prototype.bezierTangent = function(path, t){};
PathMaker.prototype.splitBezier = function(points, t){};
PathMaker.prototype.arc = function(start, end){};
PathMaker.prototype.getKappa = function(angle, start){};
PathMaker.prototype.circle = function(radius, start, end, x, y, reverse){};
PathMaker.prototype.ellipse = function(radiusX, radiusY, start, end, x, y , reverse/*, anchorPoint, reverse*/ ){};
PathMaker.prototype.rotateArc = function(path /*array*/ , angle){};
PathMaker.prototype.rotatePoint = function(point, origin, r){};
PathMaker.prototype.roundErrors = function(n, acurracy){};
PathMaker.prototype.rotate = function(path /*object or array*/ , R){};
PathMaker.prototype.moveTo = function(path /*object or array*/ , x, y){};
PathMaker.prototype.scale = function(path, x, y /* number X scale i.e. 1.2 for 120% */ ){};
PathMaker.prototype.reverse = function(path){};
PathMaker.prototype.pathItemPath = function(pathItem, toSource){};
PathMaker.prototype.merge = function(path){};
PathMaker.prototype.draw = function(item, properties){};