Karate - how to wait for assertion (negative assertion) - automated-tests

Using Karate I need to use assertion (negative assertion) but I need some repetitive check.
Example: when I delete application, it takes some time when it is removed from User Interface. I need to check If the app name is still there or not (every 3 seconds). If it is not present (the appName do not exist on page) then next test steps follow.
For assertion I use:
assert !locate('{//*[normalize-space(text()) = \'' + appName + '\']}').exists
Could you please help me with idea how to do periodically (every 3 sec) check the appName existence? Thank you.

Use waitUntil()
* def fun = function(){ return !locate('#foo').exists ? true : null }
* waitUntil(fun)
EDIT: please also note this API revision we will be doing for 0.9.6 final: https://github.com/intuit/karate/issues/1148

Related

basic firebase + dialogflow - repeated agent add dialogflow

really appreciate the helps
I have been following this video with this code.
My code looks like this
function angerEmotionCapture(agent) {
const angryTo = agent.parameters.angryDirectedTo;
return admin.database().ref('directedTo').transaction((directedTo)=>{
let target = directedTo;
agent.add(`previous entry was ${target}`);
target = angryTo;
agent.add(`new entry is ${target}`);
return directedTo;
});
}
The purpose of this is to capture a conversation topic and store it in the database.
I'm planning to use it for multiple purposes that's why I don't use context.
This code is only the first step to see if I can capture it properly.
When doing this, the agent response always look like this
previous entry was null
new entry is boss
previous entry was friends
new entry is boss
Here "friends" and "boss" are expected. However, the first repetition is not expected and it always gives null. Despite of that, this correctly update the database
I want to understand why is there a repetition here
Thanks, really appreciate the time

Count attempts in airflow sensor

I have a sensor that waits for a file to appear in an external file system
The sensor uses mode="reschedule"
I would like to trigger a specific behavior after X failed attempts.
Is there any straightforward way to know how many times the sensor has already attempted to run the poke method?
My quick fix so far has been to push an XCom with the attempt number, and increase it every time the poke method returns False. Is there any built-in mechanism for this?
Thank you
I had a similar problem when sensor mode = "reschedule", trying to poke a different path to a file based on the current time without directly referencing pendulum.now or datetime.now
I used task_reschedules (as done in the base sensor operator to get try_number for reschedule mode https://airflow.apache.org/docs/apache-airflow/stable/_modules/airflow/sensors/base.html#BaseSensorOperator.execute)
def execute(self, context):
task_reschedules = TaskReschedule.find_for_task_instance(context['ti'])
self.poke_number = (len(task_reschedules) + 1)
super().execute(context)
then self.poke_number can be used within poke(), and current time is approximately execution_date + (poke_number * poke_interval).
Apparently, the XCom thing isn't working, because pushed XComs don't seem to be available between pokes; they always return undefined.
try_number inside task_instance doesn't help either, as pokes don't count as a new try number
I ended up computing the attempt number by hand:
attempt_no = math.ceil((pendulum.now(tz='utc') - kwargs['ti'].start_date).seconds / kwargs['task'].poke_interval)
The code will work fine as long as individual executions of the poke method don't last longer than the poke interval (which they shouldn't)
Best

How to make Xll stop working (if license is invalid)?

So, if I want to write an Xll and license the code then I need a point at which to check the license file and if license is invalid then I want the Xll to stop working.
I see xlAutoOpen looks like a good place to inspect the license file. I also see that xlAutoOpen must return 1 according to the documentation, what happens if something other than 1 is returned? Can I abort the Xll opening? Can I force an unload?
Are there any better places to check the license and refuse to operate. Surely, I don't have to wait until the first worksheet function invocation.
I am unfamiliar with this framework currently so forgive newbie-ness.
EDIT: I suppose I can refuse to call xlfRegister. That will prevent operation.
EDIT2: From the Excel SDK Help file
xlAutoAdd ... can be used to ... check licensing information, for example.
Also, found that on MSDN xlAutoAdd
You should check licensing information in xlAutoOpen since this function is the first entry point to activate the XLL and is always called by Excel. If password is invalid just returns 0 to indicates failure to excel and do not register your UDFs (quit before to call xlfRegister).
I have noticed that if you register your UDFs and that you returns 0 ,
the xll is still loaded and UDFs are available, so the return
variable from xlAutoOpen does not seem to be taken into account by
Excel but by convention I believe it is better to keep returning zero
to indicate failure.
I believe MSDN doc is misleading.
xlAutoAdd is not suitable to check license since it is an optional function that is called only when the XLL is added by the Add-In Manager or when it is opened as a document (using File/Open). I assume that you may have trial licence and so that you should check it at every load time if the user's licence is still valid.
Example
Usually, you call xlAutoOpen from xlAutoAdd so your check will still be done :
pseudo code :
int __stdcall xlAutoAdd(void)
{
if(!Isinitialised)
if( xlAutoOpen() == 0) // licence check is still performed
returns 0 ;
...
MessageBoxA(GetActiveWindow(), "Thank you to install ...", "AutoOpen", MB_OK);
Isinitialised = true;
}
since xlAutoOpen is always called by Excel you should perform a similar check inside it :
bool Isinitialised = false;
int __stdcall xlAutoOpen(void) // Register the functions
{
if(Isinitialised)
return 1;
if(!ValidLicense()) // check licence in xlAutoOpen
return 0;
// continue initialization , registration ..
.....
Isinitialised = true;
}
Finally note that you can omit xlAutoAdd because it has no adverse consequences and is not required by Excel. Personally I do not use this function.

How do I have my Bot respond with arguments?

So I've built a Telegram bot, which can receive the following commands:
/list
/info 123
This works great, as I can catch /info and pass the additional arguments as ints. But, sadly, the Telegram clients don't see /info 123 as a complete command, but just the /info part. Is there a way to make it recognize the entirety of the command as the command?
I've tried Markdown-ing it: [/info 123](/info 123), but no joy. Is this possible?
I've reached out to #BotSupport with the same question, and he/they/it responded swiftly with the following answer:
Hi, at the moment it is not possible to highlight parameters of a command. I any case, you may can find a workaround if you use correct custom keyboards ;)
— #BotSupport
Custom keyboards may be an option for someone, but not for me. The solution I've gone for is to give the command as /info123. As the bot receives all / commands, I check if the received command starts with info, and if so, I remove the info part. I convert the remaining string/int to arguments, and pass that along to the relevant command.
If you mean to pass the 123 as an argument for your command info and if you happen to use the python-telegram-bot, then here's how you do it:
dispatcher.add_handler(CommandHandler('hello', SayHello, pass_args=True))
According to the documentation: pass_args Determines whether the handler should be passed the arguments passed to the command as a keyword argument called args. It will contain a list of strings, which is the text following the command split on single or consecutive whitespace characters. Default is False.
you can use RegexHandler() to do this.
Here is an example
def info(bot, update):
id = update.message.text.replace('/info_', '')
update.message.reply_text(id, parse_mode='Markdown')
def main():
updater = Updater(TOKEN)
updater.dispatcher.add_handler(RegexHandler('^(/info_[\d]+)$', info))
updater.start_polling()
Usage
The command /info_120 will return 120
and /info_007 will return 007
UPDATE
for newer versions, you may use this method instead!
MessageHandler(filters.Regex(r'^(/info_[\d]+)$'), info)
To get the argument of command you don't even need to use pass_args as said Moein you can simply get it from context.args look at Github page. So you can pass as many arguments as you want and you will get a list of arguments! Here is an example from Github.
def start_callback(update, context):
user_says = " ".join(context.args)
update.message.reply_text("You said: " + user_says)
...
dispatcher.add_handler(CommandHandler("start", start_callback))
ForceReply
Upon receiving a message with this object, Telegram clients will display a reply interface to the user (act as if the user has selected the bot's message and tapped 'Reply'). This can be extremely useful if you want to create user-friendly step-by-step interfaces without having to sacrifice privacy mode.
a simple shot
In this case, a user should send a valid number with /audio command (e.g. /audio 3, if they forgot it, we can inform and force them to do so.
source:
https://core.telegram.org/bots/api#forcereply
This is a fairly rudimentary way of creating kwargs from user input.
Unfortunately, it does require the user to be aware of the fields that can be used as parameters, but if you can provide informative response when the user doesnt provide any detectable kwarg style messages then you could probably make a better experience.
As I say, extremely rudimentary idea, and would probably be achieved faster with the regex filters available. And this would be much more reliable when checking input from the user of the "pesky" variety.
The script relies on || delimiter preceeding the command and as is shown will trim any extra characters like new lines and spaces
You can remove the extra check for commit as this is provided in order to tell the bot that you want to save your input to the database explicitly.
def parse_kwargs(update):
commit = False
kwargs = {}
if update.message:
for args in update.message.text.split('||')[1:]:
for kw_pair in args.split(','):
key, value = kw_pair.split('=')
if key.strip() != 'commit':
kwargs[key.strip()] = value.strip()
elif key.strip() == 'commit' and value.strip().lower() == 'true':
commit = True
return kwargs, commit

Event log messages get overrriden by another event log

I create event logs for asp.net projects error logging. I do it by adding a key in regedit, and then a sub-key.
Sometimes, I create a new key and sub-key, and instead of getting a new, empty event log, I see in the event viewer that it's showing me the logs from a different project. I'm not able to find a pattern as to when this happens.
Has anyone encountered such a problem? Am I doing something wrong?
You probably want to use the EventLog.CreateEventSource API to do this - it should take care of any details for you.
A quick read thru the docs seems to show that the 1st 8 characters are checked for uniqueness...perhaps that's where your issue is?
Edit: From Reflector, the API does this...
Check for invalid characters ("non printable" based on Unicode category, \, *, ?)
Checks that the created reg key will be <= 254 characters
Checks if the source is already registered
Checks that the log name isn't reserved (AppEvent, SecEvent, SysEvent)
Checks for another log with the same beginning 8 chars
Checks that the log name doesn't exist as a source
Creates the log subkey
Initializes the log subkey with default values (MaxSize = 524288, AutoBackupLogFiles = 9. Retention = 604800, File = %SystemRoot%\System32\config\logName.Substring(0, 8) + ".evt")
If OS is not > Windows NT 5.x (Vista or higher), creates a multi string value on the logkey with logName and source name. Or, if value exists, appends source name to the existing array.
Creates a subkey for source
Initializes the source subkey with default values (EventMessageFile, ParameterMessageFile, CategoryMessageFile, CategoryCount)
It seems that the problem was that we had already created an event log with that name, and even though we deleted it, it didn't help. The solution was to create an event log with a different name.

Resources