Here's the flow of conversation that I am trying to achieve using Houndify and it's Custom Commands feature:
User: "Add task"
Houndify: "What is name of your task?"
User: <Says Task name>
Houndify: "What is end date of task?"
User: "This Saturday"
The Task Name from the user can be any word in English. I need to be able to capture what the user says and trigger the response of ClientMatch #2.
I have used Custom Commands and here's what I have done:
In ClientMatch #1, I have the expression ("add" | "insert").[("a")] .("task"). I also have the response "What is name of your task?".
What I currently have:
In ClientMatch #2, I have the expression [("*")] as a wildcard. I have the response "What is end date of task?"
What I must have:
In ClientMatch #2, I need to have an expression that captures User's <Task name> instead of [("*")]. And then trigger the same response as above.
I am able to reach ClientMatch #1 easily as it matches the patter of query. But once ClientMatch #1 is triggered, Houndify does not seem go to ClientMatch #2. Or so I think.
What is the expression that is equivalent to a wildcard that can trigger ClientMatch #2? Or how do I capture User's response where the User simply states the task name?
Thank you!
Please refer houndify
CONVERSATION-STATE
https://www.houndify.com/docs#conversation-state
Related
I want to implement a command in my bot, to allow fetching messages from a channel and process them further.
I tried to look for how to fetch messages from a specific channel, but could not find an explicit answer to it, except most of the forum pages simply refer to the API page, with some saying trying the discord.utils.get method.
I am wondering if it would be something like this, but I could not find the matching methods/attributes that I can use to do this:
#bot.command(name='fetchmessages', help='....')
async def fetchmessages(ctx, from_channel_id:str, from_date:str):
#check if the channels already exist
channel = discord.utils.get(ctx.guild.channels, id=from_channel_id)
from_date = .... #code to parse the string to a date object
discord.utils.get(channel.messages, # Q1
from=from_date) # Q2
####
However, I cannot really do this because
Q1: assuming the channel is a TextChannel link, the class does not have an attribute that gives me all the messages from that channel, but only last_message. While TextChannel has a method fetch_message but that only gets a single message with an ID parameter
Q2: I am not sure if I can pass a date object like this, because the API for discord.utils.get does not explicitly say what attributes (**attrs) can be specified.
Any hints much appreciated.
Thanks
You are right that you can't use fetch_message because it only returns a single message, but you can use channel.history (link can be found here)
from datetime import datetime
#bot.command()
async def fetchmessages(ctx, from_channel_id:str, from_date:str):
channel = client.get_channel(int(from_channel_id))
date = datetime.strptime(from_date, '%b %d %Y %I:%M%p')
messages = await ctx.channel.history(limit=200, after=date).flatten()
#To do something with messages
Referenced this question regarding string to datetime object.
Q1: you can use the channel.history() function but for that, you would have to have the read_message_history permissions to get access to those messages
Q2: as you can read in discord.utils.get "To have a nested attribute search (i.e. search by x.y) then pass in x__y as the keyword argument." you can access whatever variable you want but instead of using '.' you need to use '_'
so for example
discord.utils.get(channel.messages,created_at=from_date)
another thing that I just want to point out is the date attribute you're trying to get by has to be a datetime.datetime object
I need to be able to prompt for user input (username, password and authorisation code) so my tests can access a GUI. These details cannot be stored as test data, so they'll have to be input part way through a test.
I've tried the following, but it's not working how I want:
Feature file:
Feature: user input as part of a test
Scenario: user input at the start
Given the test requires a name
Step definition:
Given(/^the test requires a name$/) do
get_a_name
end
Method:
def get_a_name
puts "Gimme a name"
#input_name = gets.chomp
puts "Hello #{#input_name}"
end
Result:
Gimme a name
Hello Feature: user input as part of a test
Any help would be much appreciated. Thanks.
You have a number of options when dealing with external services in test automation. In this particular case you can
Change your source so the authentication behaves differently when testing
OR
Record a response from the external service and use that response instead of going to the external service (see https://github.com/vcr/vcr). As the response is recorded you will know the authorisation code
OR
Use a test version of the external service which gives back know responses
I suspect there are a number of other solutions, but all three of the above are used widely and work fine.
There is certainly no need to have manual interactions to test your system unless you are running your tests against a production system (which is a very bad idea!).
I've the following recipe used to create some users, add them to a group and set the password to expire at the first login.
search(:users, '*:*').each do |user|
userPassword = "$1$scmdevop$ZDTyqia9RXSrpHGK75FjN/"
user user['id'] do
comment user['comment']
home user['home']
shell user['shell']
manage_home true
password "#{userPassword}"
end
if user['sudo'] then
group "#{node.default["sudogroup"]}" do
action :modify
members user['id']
append true
end
end
if (user['resetPassword'] == nil) || (user['resetPassword']) then
bash 'setExporation' do
code 'chage -d 0 ' + user['id']
user 'root'
end
end
end
The problem is that in this way it will continue to reset the password and set the espiration at every run so I was trying to find how to make it conditionally. I would like to use the following command to check if the user exist
grep -qs #{user["id"]} /etc/passwd
The problem is that I can use the not_if clause only in the first resource because after that the user has been clearly created. Is there a way to get the entire block of three resources being conditional to a shell exit code?
Thanks,
Michele.
What you probably want is a notification from the user resource, but this might be a little hard because that would trigger on any change, not just creation. The underlying problem here is that the desired behavior you stated is expressed in procedural terms, not in terms of convergent state. Best approach is probably to build a custom resource to hide some of this logic, but at heart what you want is an if statement like you already have.
Here as you can see I am trying fetch a value from .yml file located in config/environments in Examples: table.
But instead of fetching it is sending the value as it is?
Is it possible to pass parameter like this? If Yes, how?
If not, which Ruby or Cucumber feature/concept refrains user to do so and why?
Feature: Verify login of all test users
I want to verify all test users can login.
Scenario Outline: Login as different users on the website
Given I am on login page
When I enter "<username>" and password
Then I click Login button
And I see "<user>" successfully logged in
Examples:
|user|username|
|testuser1|#{FigNewton.test1_email}|
|testuser2|FigNewton.test2_email|
First of all this is a pretty poor feature, better would be
Scenario: Test Users can login
Given there are some test users
When the test users login
Then all test users should be logged in
or something like that. Features are for stating what you want to do and why, not how you do things.
IF you do the above then all the programming will be done in the step definitions. This will allow you do do whatever you want.
You can implement this quite easily e.g
Given 'there are some test users' do
#test_users = create_test_users
end
When 'the test users login' do
#login_results = login_each(#test_users)
end
Then 'all test users should be logged in' do
expect(check_for_errors(#login_results).count).to eql 0
end
then implement the methods you need in a step helper e.g
module TestUsersLoginStepHelper
def create_test_users
...
def login_each(users)
users.each do
...
...
end
World TestUsersLoginStepHelper
By putting all the work in the step definitions, you make your live much easier, as you can use the full power of ruby to do what you need
Answer to query1:
You can parametrize via Examples: table but not directly passing value using FigNewton gem because it is a .feature file not a Ruby .rb file.
Answer to query2:
How you do it:
Parametrize and Loop it on username and in you steps definition mention what to do when particular user name found. By this you can easily parametrize.
Examples:
|user|username|
|testuser1|test1|
|testuser2|test2|
Step definition
When(/^I enter "([^"]*)" and password$/) do |username|
case username
when 'test1'
on(LoginPage).user_email = FigNewton.test1_email
when 'test'
on(LoginPage).user_email = FigNewton.test2_email
end
....
....
end
You can use this DDD scenario in project whenever its needed - by using this we do not need to create multiple test cases, it will fetch data value from Example outline.
Feature file : Test case
Scenario Outline: Login to application
When I enter "username>" and "password>"
Then I click Login button
And I see user successfully logged in
Examples:
|username|password|
|abc#gmail.com|Test1234!|
|abc#yahoo.com|Test1234!|
Step definition:
When(/^I enter "([^"])" and "([^"])"$/) do |username,password|
sleep 20
on(Login).email_edit_text_element.send_keys username
on(Login).password_edit_text_element.send_keys password
end
Then(/^I click Login button$/) do
sleep 20
on(Login).login_button_element.click
end
Then(/^I see user successfully logged in$/) do
expect(on(Login).account_bg_cover_element.displayed?).to be_truthy
puts 'Login Success'
end
In ruby file, you have created methods, you are calling that methods in step definition.
It will work. make sure about the name of parameter you are passing.
I want to reuse some Cucumber steps but can't seem to find the right way.
I want to write a step like:
Given /^I login with (.*) credentials$/ |type|
# do stuff with type being one of "invalid" or "valid"
end
But then have another step like:
Given /^I login successfully$
# call "Given I login with valid credentials"
end
So in testing user authentication I can use the former, but most other places, I can use the latter, and not actually have to repro code.
Is there a way to call that other step, or do I just put the logic in a helper method, and call said method from each task (basically a method extraction refactoring, which, after reading my question makes me believe that's actually the best way anyway)?
Note that the method for calling steps within steps has changed in recent versions of cucumber, which you'll see if you get an error like "WARNING: Using 'Given/When/Then' in step definitions is deprecated, use 'step' to call other steps instead:/path/to/step_definitions/foo_steps.rb:631:in `block in '
". See the cucumber wiki for details.
The gist of the change is that you should now use the step or steps methods.
When /^I make all my stuff shiny$/
step "I polish my first thing"
end
When /^I make all my stuff shiny$/
steps %Q{
When I polish my first thing
When I shine my second thing
}
end
UPDATE: The method described below has been deprecated. The recommended way to call a step from within another step now looks like this:
Given /^I login successfully$/
step "I login with valid credentials"
end
Old, deprecated method (for reference):
You can call steps from other steps like this:
Given /^I login successfully$/
Given "I login with valid credentials"
Then "I should be logged in"
end
If all of the scenarios within a feature require this (or other steps), you can also add a Background to each features, with the common steps, like so:
Background:
Given I log in with valid credentials
Scenario: Change my password
Given I am on the account page
Calling steps from step definitions is a bad practice and has some disadvantages:
If scenario will fail and there are nested step invocations, you will get only the last invoked step definition in the stack trace. It may be hard to find from which place that last stepdef was called
Call to stepdef is sometimes harder to find and read than ruby method
Ruby methods give you more power than calling steps from step defs
Aslak Hellesøy recommends to extract popular actions to World instead of reusing steps. It isolates those actions in one place, makes this code easier to find. You can extract code to usual Ruby classes or modules as well.
#/support/world_extensions.rb
module KnowsUser
def login
visit('/login')
fill_in('User name', with: user.name)
fill_in('Password', with: user.password)
click_button('Log in')
end
def user
#user ||= User.create!(:name => 'Aslak', :password => 'xyz')
end
end
World(KnowsUser)
#/step_definitions/authentication_steps.rb
When /^I login$/ do
login
end
Given /^a logged in user$/ do
login
end
Here is a useful discussion on the subject in Cucumber mailing list - link
Best wrap your steps in %{} rather than quotes. Then, you don't need to escape double quotes which you'll need to use frequently.:
Given /^I login successfully$
step %{I login with valid credentials}
end
Given /^I login with (.*) credentials$/ |type|
# do stuff with type being one of "invalid" or "valid"
end
Reuse keywords in feature file which will provide code reusability.
It is highly NOT recommended to call step defs within step defs.
I would write my feature file this way,
Scenario Outline: To check login functionality
Given I login with "<username>" and "<password>"
Then I "<may or may not>" login successfully
Examples:
|username|password|may or may not|
|paul |123$ |may |
|dave |1111 |may not |
In my step definition, (This is Java)
#Given(I login with \"([^\"]*)\" and \"([^\"]*)\"$)
public void I_login_with_and(String username, String password){
//login with username and password
}
#Then(I \"([^\"]*)\" login successfully$)
public void I_login_successully_if(String validity){
if(validity.equals("may")){
//assert for valid login
}
else
if(validity.equals("may not")){
//assert for invalid login
}
}
In this way, there is a lot of code reusability.
Your same Given and Then handles both valid and invalid scenarios.
At the same time, your feature file makes sense to the readers.