Best Python code snippet using hypothesis
views.py
Source:views.py
1from django import template2from django.contrib import messages3from django.contrib.auth.decorators import login_required4from django.contrib.auth.models import User5from django.contrib.sites.shortcuts import get_current_site6from django.shortcuts import render, redirect7from django.template.loader import render_to_string8from onboard.models import Profile9from .models import Cached_Matches, Recent_Matches, Cached_List_Matches10from .user_match import quick_match_prototype, get_match_list, list_match11from .user_match import to_user_list, to_user_string, dequeue, enqueue12from sys import stderr13from .tasks import send_survey14from datetime import timedelta15from django.utils import timezone16from .forms import MatchConfigurationForm17#from post_office import mail18from account.models import NotificationItem19from account.pull_notif import pull_notif, mark_read20from mockingbird.decorators import onboard_only21class MatchedUser(object):22 def __init__(self, username: str, email: str, industry1: str, industry2: str, year: str):23 self.username = username24 self.email = email25 if industry2 == 'None':26 self.industry = industry127 else:28 self.industry = industry1 + ', ' + industry229 self.year = year30 def getUsername(self):31 return self.username32 def getEmail(self):33 return self.email34 def getIndustry(self):35 return self.industry36 def getYear(self):37 return self.year38register = template.Library()39def _on_accept_home(request, username):40 if request.method == 'POST':41 t_username = username42 target = User.objects.filter(username=str(t_username))[0]43 if not target: return False44 print(t_username)45 # change sender to blocked46 request.user.profile.is_waiting = True47 request.user.profile.match_name = str(t_username)48 request.user.profile.is_sender = True49 request.user.profile.save()50 request.user.profile.request_name = str(t_username)51 # change target's info52 target.profile.requested_names = target.profile.requested_names + "," + request.user.username53 #target.profile.is_matched = True54 target.profile.is_sender = False55 target.profile.is_waiting = False56 target.profile.has_request = True57 target.profile.save()58 current_site = get_current_site(request)59 # logic to send email to the target if user accepts emails60 if target.profile.receive_email:61 subject = '[MockingBird] You have a Match!'62 message = render_to_string('matching/matching_email.html', {63 'user': target,64 'domain': current_site.domain,65 })66 target.email_user(subject, message)67 # logic to create a notification for the target68 NotificationItem.objects.create(type="MR", user=target, match_name=str(request.user.username))69 return True70def _on_accept(request):71 if request.method == 'POST':72 t_username = request.POST.get('username')73 # change sender to blocked74 request.user.profile.is_waiting = True75 request.user.profile.match_name = str(t_username)76 request.user.profile.is_sender = True77 request.user.profile.save()78 request.user.profile.request_name = str(t_username)79 # change target's info80 target = User.objects.filter(username=str(t_username))[0]81 target.profile.requested_names = target.profile.requested_names + "," + request.user.username82 #target.profile.is_matched = True83 target.profile.is_sender = False84 target.profile.is_waiting = False85 target.profile.has_request = True86 target.profile.save()87 current_site = get_current_site(request)88 # logic to send email to the target if user accepts emails89 if target.profile.receive_email:90 subject = '[MockingBird] You have a Match!'91 message = render_to_string('matching/matching_email.html', {92 'user': target,93 'domain': current_site.domain,94 })95 target.email_user(subject, message)96 # logic to create a notification for the target97 NotificationItem.objects.create(type="MR", user=target, match_name=str(request.user.username))98 return True99# Create your views here.100@login_required(login_url='/login/')101@onboard_only102def match_view(request):103 L_SIZE = 10104 # # clear messages105 ## storage = messages.get_messages(request)106 # for message in storage:107 # str(message)108 # clear messages109 storage = messages.get_messages(request)110 for message in storage:111 str(message)112 my_profile = Profile.objects.get(id=request.user.id)113 recent = Recent_Matches.objects.get(user=my_profile.user)114 recent_list = to_user_list(recent.matches, 'p')115 print(type(recent_list))116 match_cache = Cached_Matches.objects.get(user=my_profile.user)117 match_cache_list = to_user_list(match_cache.matches, 'p')118 # if has a deleted user remake it119 #if match_cache_list == "Deleted User":120 # matchlist_create(request.user)121 # match_cache = Cached_Matches.objects.get(user=my_profile.user)122 # match_cache_list = to_user_list(match_cache.matches, 'p')123 match_list = match_cache_list124 if len(match_list) is 0:125 match_list = get_match_list(my_profile, recent_list)126 print(match_list)127 # match = quick_match_prototype(my_profile)128 if match_list is not None and len(match_list) is not 0:129 print("here")130 match = User.objects.get(username=match_list[0])131 match_profile = Profile.objects.get(user=match)132 recent_list = enqueue(recent_list, match_profile, L_SIZE)133 recent.matches = to_user_string(recent_list)134 recent.save()135 matchedUser = MatchedUser(username = str(match.username),136 email = str(match.email),137 industry1 = str(match.profile.industry_choice_1),138 industry2 = str(match.profile.industry_choice_2),139 year=str(match.profile.year_in_school))140 request.session['matchedUser'] = matchedUser.__dict__141 match_list = dequeue(match_list)142 match_cache.matches = to_user_string(match_list)143 match_cache.save()144 print("cache after matching: " + match_cache.matches, file=stderr)145 else:146 request.session['matchedUser'] = None147 return redirect('../matchresults/')148# @login_required149# def matchagain_view(request):150# my_profile = Profile.objects.get(id=request.user.id)151# match_cache = Cached_Matches.objects.get(user=my_profile.user)152# match_cache_list = to_user_list(match_cache.matches)153@login_required(login_url='/login/')154@onboard_only155def matchresults_view(request):156 '''157 storage = messages.get_messages(request)158 msgs = []159 username = ''160 email = ''161 industry = ''162 for message in storage:163 print(message, file=stderr)164 msgs.append(message)165 if len(msgs) > 0:166 username = msgs[0]167 email = msgs[1]168 industry = msgs[2]169 messages.add_message(request, messages.INFO, username)170 messages.add_message(request, messages.INFO, email)171 messages.add_message(request, messages.INFO, industry)172 '''173 matchedUser = request.session.get('matchedUser', None)174 matchedUsers = []175 if matchedUser is not None:176 request.session['matchedUser'] = matchedUser177 matchedUsers.append(matchedUser)178 pulled = pull_notif(request.user)179 context = {#180 #'msgs': msgs,181 #'username': username,182 #'email': email,183 #'industry': industry,184 'has_unread': pulled[0],185 'notif': pulled[1],186 'matchedUsers': matchedUsers,187 'configured': False188 }189 if request.method == 'POST' and 'markread' in request.POST:190 mark_read(request.user)191 pulled = pull_notif(request.user)192 context['has_unread'] = pulled[0]193 context['notif'] = pulled[1]194 else:195 val_acceptance = _on_accept(request)196 if (val_acceptance):197 # requested_names = str(request.user.profile.requested_names) + request.POST.get('username') + ","198 # request.user.profile.requested_names = requested_names199 # request.user.profile.save()200 return redirect('request_info')201 return render(request, 'matching/matchresults.html', context)202@login_required(login_url='/login/')203@onboard_only204def matchlist_view(request):205 if request.method == 'POST':206 # my_profile = Profile.objects.get(id=request.user.id)207 # form = MatchConfigurationForm(request.POST, instance=request.user.profile)208 # rankers = []209 # industryChoice = 'Industry 1'210 # if form.is_valid():211 # form.save()212 # rankers = request.POST.getlist('rank_by')213 # industryChoice = request.POST.get('industry_match')214 # matches = list_match(my_profile, rankers, industryChoice)215 my_profile = Profile.objects.get(id=request.user.id)216 rankersString = str(my_profile.rank_by)217 rankers = []218 if (rankersString is not None):219 rankers = rankersString.split(',')220 if "" in rankers:221 rankers.remove("")222 match_list = list_match(my_profile, rankers, my_profile.industry_match)223 matches = to_user_string(match_list)224 match_cache = Cached_List_Matches.objects.filter(user=my_profile.user)225 if (len(match_cache) == 0):226 match_cache = Cached_List_Matches.objects.create(user=my_profile.user, matches=matches)227 else:228 match_cache = list(match_cache)[0]229 match_cache.matches = matches230 match_cache.save()231 matchedUsers = []232 for match in match_list:233 matchedUser = MatchedUser(username = str(match.user.username), email = str(match.user.email),234 industry1 = str(match.industry_choice_1), industry2 = str(match.industry_choice_2), year=str(match.year_in_school))235 matchedUsers.append(matchedUser.__dict__)236 request.session['matchedUsers'] = matchedUsers237 else:238 return redirect('home')239 return redirect('../matchlistresults/')240# Creats a list match caching241def matchlist_create(user):242 my_profile = user.profile243 rankers = my_profile.rank_by244 match_list = list_match(my_profile, rankers, my_profile.industry_match)245 matches = to_user_string(match_list)246 match_cache = Cached_List_Matches.objects.filter(user=my_profile.user)247 if (len(match_cache) == 0):248 match_cache = Cached_List_Matches.objects.create(user=my_profile.user, matches=matches)249 else:250 match_cache = list(match_cache)[0]251 match_cache.matches = matches252 match_cache.save()253# Grabs the cache match list for the given user254def matchlist_get(request):255 my_profile = Profile.objects.get(id=request.user.id)256 match_cache = Cached_List_Matches.objects.filter(user=my_profile.user)257 # in the case that the user doesn't have a cached match list yet258 if not match_cache:259 matchlist_create(request.user)260 match_cache = Cached_List_Matches.objects.filter(user=my_profile.user)[0]261 match_cache_list = to_user_list(match_cache.matches, 'u')262 # If there is a deleted user in the cache, refresh cache then return the new cache list.263 if match_cache_list == 'Deleted User':264 matchlist_create(request.user)265 match_cache = Cached_List_Matches.objects.filter(user=my_profile.user)[0]266 match_cache_list = to_user_list(match_cache.matches, 'u')267 return match_cache_list268@login_required(login_url='/login/')269@onboard_only270def matchlistresults_view(request):271 matchedUsers = request.session.get('matchedUsers', None)272 pulled = pull_notif(request.user)273 if request.method == 'POST' and 'markread' in request.POST:274 mark_read(request.user)275 pulled = pull_notif(request.user)276 context = {277 'has_read': pulled[0],278 'notif': pulled[1],279 'matchedUsers': matchedUsers,280 'configured': True281 }282 val_acceptance = _on_accept(request)283 if (val_acceptance):284 return redirect('request_info')285 return render(request, 'matching/matchresults.html', context)286@login_required(login_url='/login/')287@onboard_only288def matchconfig_view(request):289 initial_data = {290 'industry_match': request.user.profile.industry_match,291 'rank_by': request.user.profile.rank_by,292 }293 form = MatchConfigurationForm(instance=request.user.profile, initial=initial_data)294 form.fields['industry_match'].label = "Which industry or industries are you looking to be matched on?"295 form.fields['rank_by'].label = "Which fields do you want to rank your matches by? (Ctrl or Cmd + Click) to select multiple."296 pulled = pull_notif(request.user)297 if request.method == 'POST' and 'markread' in request.POST:298 mark_read(request.user)299 pulled = pull_notif(request.user)300 return render(request, 'matching/match.html', {'form': form,301 'has_unread': pulled[0],302 'notif': pulled[1]})303@login_required(login_url='/login/')304@onboard_only305def update_matchconfig(request):306 if request.method == 'POST':307 my_profile = Profile.objects.get(id=request.user.id)308 form = MatchConfigurationForm(request.POST, instance=request.user.profile)309 if form.is_valid():310 form.save()311 matchlist_create(request.user)312 else:313 return redirect('matchconfig')314 return redirect('home')315@login_required(login_url='/login/')316@onboard_only317def request_info(request):318 pulled = pull_notif(request.user)319 if request.user.profile.is_matched or request.user.profile.is_waiting or request.user.profile.has_request:320 requested_names = str(request.user.profile.requested_names).split(",")321 requested_users = []322 for name in requested_names:323 if name is not '':324 requested_users.append(User.objects.get(username=name))325 if request.method == 'POST' and 'markread' in request.POST:326 mark_read(request.user)327 pulled = pull_notif(request.user)328 requestee = request.session.get('matchedUser', None)329 request_match = ""330 request_matches = User.objects.filter(username=request.user.profile.match_name)331 if request_matches:332 request_match = request_matches[0]333 # if (str(target.profile.industry_choice_2) == 'None'):334 # industry = target.profile.industry_choice_1335 # else:336 # industry = str(target.profile.industry_choice_1) + ', ' + str(target.profile.industry_choice_2)337 context = {338 'users': requested_users,339 'requestee': requestee,340 'request_match': request_match,341 # 'username': target.username,342 # 'industry': industry,343 # 'year': target.profile.year_in_school,344 # 'role': target.profile.role,345 # 'email': target.email,346 'has_unread': pulled[0],347 'notif': pulled[1],348 'request': request349 }350 return render(request, 'matching/request_info.html', context)351 else:352 if request.method == 'POST' and 'markread' in request.POST:353 mark_read(request.user)354 pulled = pull_notif(request.user)355 context = {356 'has_unread': pulled[0],357 'notif': pulled[1]358 }359 return render(request, 'matching/no_request.html', context)360@login_required(login_url='/login/')361@onboard_only362def accept_request(request):363 if not request.user.profile.has_request:364 pulled = pull_notif(request.user)365 if request.method == 'POST' and 'markread' in request.POST:366 mark_read(request.user)367 pulled = pull_notif(request.user)368 context = {369 'has_unread': pulled[0],370 'notif': pulled[1]371 }372 return render(request, 'matching/no_request.html', context)373 else:374 t_username = request.POST.get('match')375 requested_users = str(request.user.profile.requested_names).split(",")376 print("t_username: " + t_username, file=stderr)377 # change target's settings378 for name in requested_users:379 if name == "":380 continue381 print("requested user: " + name, file=stderr)382 target = User.objects.get(username=name)383 if t_username == name:384 target.profile.is_matched = True385 target.profile.match_name = request.user.username386 print("this user is a match", file=stderr)387 else:388 target.profile.is_matched = False389 target.profile.match_name = ""390 print("this user is not a match", file=stderr)391 target.profile.is_waiting = False392 target.profile.is_sender = False393 target.profile.save()394 # change sender and accepter to matched395 request.user.profile.is_matched = True396 request.user.profile.has_request = False397 request.user.profile.requested_names = ""398 request.user.profile.match_name = t_username399 request.user.profile.save()400 # make notification item for target401 NotificationItem.objects.create(type="MA", user=target, match_name=str(request.user.username))402 current_site = get_current_site(request)403 # logic to send email to the target404 if target.profile.receive_email:405 subject = '[MockingBird] Your Match has been confirmed!'406 message = render_to_string('matching/match_confirmed.html', {407 'user': target,408 'domain': current_site.domain,409 })410 target.email_user(subject, message)411 #send_survey(request, target, str(target.profile.match_name), str(t_username))412 send_time = timezone.now() + timedelta(seconds=30)413 #send_survey.apply_async(eta=send_time, args=(request.user, target, current_site))414 send_survey.apply_async(eta=send_time, args=(request.user, target, current_site))415 matchedUser = MatchedUser(username = str(target.username),416 email = str(target.email),417 industry1 = str(target.profile.industry_choice_1),418 industry2 = str(target.profile.industry_choice_2),419 year = str(target.profile.year_in_school))420 # notification for the send survey notification421 request.session['matchedUser'] = matchedUser.__dict__422 return redirect('request_info')423@login_required(login_url='/login/')424@onboard_only425def confirm_cancel_request(request):426 match = None427 if request.user.profile.is_sender and request.user.profile.is_waiting:428 match = request.user.profile.match_name429 else:430 match = request.POST.get('match')431 # if match accepted/declined request already432 if match == None:433 match = request.user.profile.match_name434 # if match declined435 if not match:436 return render(request, 'matching/done_cancel.html')437 # if match accepted438 target = User.objects.get(username=match)439 email = target.email440 #print("hello match:", match, email)441 context = {442 'match': match,443 'email': email,444 }445 return render(request, 'matching/cannot_cancel.html', context)446 target = User.objects.get(username=match)447 pulled = pull_notif(request.user)448 print("my match")449 if request.method == 'POST' and 'markread' in request.POST:450 mark_read(request.user)451 pulled = pull_notif(request.user)452 context = {453 'username': target.username,454 'has_unread': pulled[0],455 'notif': pulled[1],456 'match': match,457 }458 return render(request, 'matching/confirm_cancel.html', context)459@login_required(login_url='/login/')460@onboard_only461def done_cancel(request):462 if request.method == 'POST' and 'markread' in request.POST:463 storage = messages.get_messages(request)464 msgs = []465 for m in storage:466 msgs.append(m)467 mark_read(request.user)468 pulled = pull_notif(request.user)469 context = {470 'username': msgs[0],471 'has_unread': pulled[0],472 'notif': pulled[1],473 }474 return render(request, 'matching/done_cancel.html', context)475 # update target's info476 match = request.POST.get('match')477 target = User.objects.get(username=match)478 # case where they're trying to go to this url forcefully479 if not match or match == "None":480 return redirect('../default')481 # make a notification for the target482 # if user is sender, they are canceling483 if request.user.profile.is_sender:484 # update own info485 request.user.profile.is_waiting = False486 request.user.profile.is_sender = False487 request.user.profile.match_name = "None"488 request.user.save()489 # print("here")490 # if they are only one in the request491 request_names = target.profile.requested_names.split(",")492 if len(request_names) == 0:493 target.profile.has_request = False494 else:495 # remove their name from request_names496 new_names = []497 for x in request_names:498 if x and x != request.user.username:499 new_names.append(x)500 if len(new_names) == 0:501 target.profile.has_request = False502 target.profile.requested_names = ""503 else: # else reset the names504 target.profile.requested_names = ",".join(new_names)505 if target.profile.receive_email:506 # send email that the match has been rejected507 subject = '[MockingBird] Canceled Match Request :('508 message = render_to_string('matching/cancel_email.html', {509 'user': target,510 'cancel_username': request.user.username,511 })512 target.email_user(subject, message)513 matchlist_create(request.user)514 NotificationItem.objects.create(type="MC", user=target, match_name=str(request.user.username))515 # if user is not the sender, they are rejecting someone516 else:517 target.profile.is_sender = False518 target.profile.is_waiting = False519 target.profile.match_name = ""520 # update current user521 requested_names = str(request.user.profile.requested_names).split(",")522 new_names = []523 for x in requested_names:524 if x and x != target.username:525 print(x)526 new_names.append(x)527 # print("rejecting")528 # print(new_names)529 # if none remaining, change to false530 if len(new_names) == 0:531 request.user.profile.has_request = False532 request.user.profile.requested_names = ""533 else: #else reset the names534 request.user.profile.requested_names = ",".join(new_names)535 # send email536 if target.profile.receive_email:537 # send email that the match has been rejected538 subject = '[MockingBird] Rejected Match Request :('539 message = render_to_string('matching/reject_email.html', {540 'user': target,541 'cancel_username': request.user.username,542 })543 target.email_user(subject, message)544 NotificationItem.objects.create(type="MD", user=target, match_name=str(request.user.username))545 target.profile.save()546 request.user.profile.save()547 pulled = pull_notif(request.user)548 context = {549 'username': target.username,550 'has_unread': pulled[0],551 'notif': pulled[1],552 }553 messages.add_message(request, messages.INFO, str(target.username))554 return render(request, 'matching/done_cancel.html', context)555def send_request_home(request):556 _on_accept(request)...
match_server.py
Source:match_server.py
1# -*- coding: utf-8 -*-2import tornado.ioloop3import tornado.httpserver4import tornado.web5import tornado.options6import pymongo7import json8import sys9sys.path.append('../common/')10from db_api import match_db_api, jifen_db_api, shooter_db_api11from tornado.options import define, options12import base_server13from cache import match_cache14define("port", default=21000, help="run on the given port", type=int)15define("ip", default="0.0.0.0", help="server_ip", type=str)16class MatchHandler(base_server.BaseHandler):17 def parse(self):18 self.compname = self.get_argument('compname')19 def get_data_from_db(self):20 now_comp_info = match_db_api.get_now_comp_info(self.compname)21 season = now_comp_info["season"]22 match_list = match_db_api.get_match_list(self.compname, season)23 matches = match_db_api.process_match_list(match_list)24 ret = {}25 ret["comp_info"] = now_comp_info26 ret["match_list"] = matches27 return ret28 def get_data_from_cache(self):29 return match_cache.get_match_list_cache(self.compname)30 def set_cache(self, value):31 match_cache.set_match_list_cache(self.compname, value)32class JifenHandler(base_server.BaseHandler):33 def parse(self):34 self.compname = self.get_argument('compname')35 def get_data_from_db(self):36 now_comp_info = match_db_api.get_now_comp_info(self.compname)37 season = now_comp_info["season"]38 jifen_list = jifen_db_api.get_team_jifen_list(self.compname, season)39 jifens = []40 for jifen in jifen_list:41 jifens.append(jifen)42 ret = {}43 ret["comp_info"] = now_comp_info44 ret["jifen_list"] = jifens45 return ret46 def get_data_from_cache(self):47 return match_cache.get_jifen_list_cache(self.compname)48 def set_cache(self, value):49 match_cache.set_jifen_list_cache(self.compname, value)50class ShooterHandler(base_server.BaseHandler):51 def parse(self):52 self.compname = self.get_argument('compname')53 def get_data_from_db(self):54 now_comp_info = match_db_api.get_now_comp_info(self.compname)55 season = now_comp_info["season"]56 shooter_list = shooter_db_api.get_shooter_list(self.compname, season)57 shooters = []58 for shooter in shooter_list:59 shooters.append(shooter)60 ret = {}61 ret["shooter_list"] = shooters62 ret["comp_info"] = now_comp_info63 return ret64 def get_data_from_cache(self):65 return match_cache.get_shooter_list_cache(self.compname)66 def set_cache(self, value):67 match_cache.set_shooter_list_cache(self.compname, value)68if __name__ == "__main__":69 tornado.options.parse_command_line()70 app = tornado.web.Application(handlers=[(r"/match", MatchHandler), (r"/jifen", JifenHandler), (r"/shooter", ShooterHandler)])71 http_server = tornado.httpserver.HTTPServer(app, xheaders=True)72 http_server.listen(options.port, address=options.ip)...
ConstantFreqMatcher.py~
Source:ConstantFreqMatcher.py~
1#!/usr/bin/env python2.72##-*- mode:python;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t;python-indent:2 -*-'3#author: Oliver Lange4# a special frequency matcher which is optimized for fast matching5#6# requirements: small relevant frequency interval for each atom7# frequencies do not change8try:9 import scipy10 import scipy.spatial11 import numpy as np12except:13 pass14class ConstantFreqMatcher:15 class RuleMatchCache:16 def __init__( self, atoms, freqs, freq_tree, scaling ):17 self.atoms=atoms18 self.freqs=freqs19 self.kdtree=freq_tree20 self.scaling=scaling21 def find_matches( self, freqs ):22 x = np.array( freqs ) * self.scaling23 return [ self.atoms[i] for i in self.kdtree.query_ball_point( x, 1.0 ) ] #radius 1 because the tolerances are already scaled in24 def __init__( self, resonances ):25 self.resonances=resonances26 self.match_cache={}27 def set_raw_matches( self, rule, matches ):28 atom2reso = {}29 #if two dimensional matches make 2-dim kd-tree30 #when trying to find matches retrieve those that are within tol1,tol2 radius of peak-freq31 #this requires a totally different interface than other freq_matchers32 #need to treat floating resonances --> same resonance (the representating) has multiple frequencies33 # is added to kd-tree with different freqs...34 scaling=1.0/np.array( rule.tolerances )35 for match in matches:36 try:37 reso = []38 for atom in match:39 reso.append( self.resonances.by_chemical_atom( atom )._freq )40 atom2reso[match]=reso41 except KeyError:42 pass43 atoms=atom2reso.keys()44 freqs = np.array( atom2reso.values() )45 freq_tree=scipy.spatial.KDTree( freqs*scaling )46 self.match_cache[ id(rule) ]=ConstantFreqMatcher.RuleMatchCache( atoms, freqs, freq_tree, scaling )47 def find_matches( self, rule, freq, raw_matches ):48 try:49 return self.match_cache[ id(rule) ].find_matches( freq )50 except KeyError:51 self.set_raw_matches( rule, raw_matches )...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!