How to get scenario name from a scenario outline in cypress gherkin setup? - cucumber

Suppose I have a test case like -
Scenario: Scenario to verify Title Matched
When Navigate to the App "Facebook"
Then verify the "TitleName" Field
How could I get the scenario name from the step definition methods corresponding to " When Navigate to the App Facebook" and "Then verify the "TitleName" Field"
Step definitions methods are -
When('Navigate to the App {string} for demo',(AppURL:string)=>{
if(AppURL=="FaceBook"){
}
});
Then('verify the Title of the page for demo',()=>
{
SampleAPPUI.verfiyTitledemo('');
});
Note: I am using cypres-cucumber with typescript

I'm doing this in a Java-Selenium-Gherkin test suite. It may not be the solution you need, but it will give you some direction about how to get the values:
#BeforeStep
public void doSomethingBeforeStep(Scenario scenario) throws Exception {
testScenario = scenario.getName().toString();
scenarioObj = scenario;
Field f = scenario.getClass().getDeclaredField("testCase");
f.setAccessible(true);
TestCase r = (TestCase) f.get(scenario);
List<PickleStepTestStep> stepDefs = r.getTestSteps()
.stream()
.filter(x -> x instanceof PickleStepTestStep)
.map(x -> (PickleStepTestStep) x)
.collect(Collectors.toList());
PickleStepTestStep currentStepDef = stepDefs.get(currentStepIndex);
testCase = currentStepDef.getStepText();
}
Also, see here and here

This works perfectly for me, though I'm not using TS, the logic behind it should give you a good starting point:
function getScenarioName(){
const _onRunnableRun = Cypress.runner.onRunnableRun
Cypress.runner.onRunnableRun = function (runnableRun, runnable, args) {
const r = runnable
const isHook = r.type === 'hook'
const isAfterAllHook = isHook && r.hookName.match(/after all/)
const isBeforeHook = isHook && r.hookName.match(/before each/)
const test = r.ctx.currentTest || r
var testTitle = test.title //this is the test title
const next = args[0]
if (
isHook &&
r.ctx.currentTest &&
r.ctx.currentTest.trueFn &&
!isAfterAllHook
) {
return next.call(this)
}
const onNext = function (err) {
const fail = function () {
return next.call(this, err)
}
const noFail = function () {
test.err = null
return next.call(this)
}
if (err) {
if (test._retries === -1) {
test._retries = getDefaultRetries()
}
if (isBeforeHook && test._currentRetry < test._retries) {
test.trueFn = test.fn
test.fn = function () {
throw err
}
return noFail()
}
}
return fail()
}
args[0] = onNext
return _onRunnableRun.apply(this, [runnableRun, runnable, args])
}
}

Related

How can I mock the webkit SpeechRecognition using Jest?

I am using webkit SpeechRecognition in my Stencil Project. I have shared function. Can anyone help me with the test cases of below function.
startDictation() {
let recognition = new webkitSpeechRecognition();
recognition.continuous = false;
recognition.interimResults = false;
recognition.lang = "en-US";
recognition.start();
recognition.onresult = (speech) => {
if (speech.results) {
ele.classList.remove("dxp-i-fill");
let result = speech.results[speech.resultIndex];
let transcript = result[0].transcript;
if (result.isFinal) {
if (result[0].confidence < 0.3) {
console.log("Unrecognized result - Please try again");
} else {
this.chatbotnputRef.value = transcript;
}
}
}
};
recognition.onerror = function () {
recognition.stop();
};
}

Unity3D: Don't continue the code until a large 3D model file is downloaded

There are around 10 3D models that I need to load from the server on a button click.
public GameObject DownloadFile(String url)
{
GameObject obj = null;
Debug.Log("url: " + url);
string path = GetFilePath(url);
Debug.Log("Path: " + path);
if (File.Exists(path))
{
Debug.Log("Found file locally, loading...");
Debug.Log(path);
obj = LoadModel(path);
return obj;
}
Debug.Log(path);
StartCoroutine(GetFileRequest(url, (UnityWebRequest req) =>
{
if (req.isNetworkError || req.isHttpError)
{
// Log any errors that may happen
Debug.Log($"{req.error} : {req.downloadHandler.text}");
}
else
{
// Save the model into a new wrapper
obj = LoadModel(path);
obj.SetActive(false);
StopAllCoroutines();
}
}));
return obj;
}
string GetFilePath(string url)
{
filePath = $"{Application.persistentDataPath}/Files/";
string[] pieces = url.Split('/');
string filename = pieces[pieces.Length - 1];
return $"{filePath}{filename}";
}
IEnumerator GetFileRequest(string url, Action<UnityWebRequest> callback)
{
using (UnityWebRequest req = UnityWebRequest.Get(url))
{
req.downloadHandler = new DownloadHandlerFile(GetFilePath(url));
yield return req.SendWebRequest();
callback(req);
}
}
GameObject LoadModel(string path)
{
ResetWrapper();
GameObject model = Importer.LoadFromFile(path);
return model;
}
This is my code right now. I call the DownloadFile function from my script with a URL as a parameter. The Download function returns a null obj because it takes time to download a huge file. So it returns obj without getting downloaded. How do I not make it return until the download is finished?
if you would do what you ask for you would completely freeze your app ... if this is what you want you could of course instead of running a Coroutine simply do
var request = GetFileRequest(url, (UnityWebRequest req) =>
{
if (req.isNetworkError || req.isHttpError)
{
// Log any errors that may happen
Debug.Log($"{req.error} : {req.downloadHandler.text}");
}
else
{
// Save the model into a new wrapper
obj = LoadModel(path);
obj.SetActive(false);
StopAllCoroutines();
}
}
while(request.MoveNext())
{
// freeze
}
return obj;
In most cases however this is absolutely not what you want ;)
Instead of giving it a return type I would rather solve this via a callback:
public void DownloadFile(String url, Action<GameObject> onResult)
{
GameObject obj = null;
Debug.Log("url: " + url);
string path = GetFilePath(url);
Debug.Log("Path: " + path);
if (File.Exists(path))
{
Debug.Log("Found file locally, loading...");
Debug.Log(path);
obj = LoadModel(path);
onResult?.Invoke(obj);
}
Debug.Log(path);
StartCoroutine(GetFileRequest(url, (UnityWebRequest req) =>
{
if (req.isNetworkError || req.isHttpError)
{
// Log any errors that may happen
Debug.LogError($"{req.error} : {req.downloadHandler.text}");
}
else
{
// Save the model into a new wrapper
obj = LoadModel(path);
obj.SetActive(false);
StopAllCoroutines();
onResult?.Invoke(obj);
}
}));
}
So instead of e.g. doing something like
var result = DownloadFile(url);
you would rather do
DownloadFile(url, result => {
// whatever to do with the result object
});

How to change the default values when add link Sharepoint 2013

In Add Link page, is it possible to change the default values like title, address, show these links to, by using URL parameters?
According to this, it seems possible in sharepoint2010. Does anyone know whether it works in 2013??
If not, is it possible to add a link by post REST API??
This problem can be solved by the steps below.
Add a custom action. Just follow the steps here.
In my case code is as below
SP.SOD.executeFunc("callout.js", "Callout", function() {
var itemCtx = {};
itemCtx.Templates = {};
itemCtx.BaseViewID = 'Callout';
// Define the list template type
itemCtx.ListTemplateType = 101;
itemCtx.Templates.Footer = function(itemCtx) {
// context, custom action function, show the ECB menu (boolean)
return CalloutRenderFooterTemplate(itemCtx, AddCustomAction, true);
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(itemCtx);
});
function AddCustomAction(renderCtx, calloutActionMenu) {
// Add your custom action
calloutActionMenu.addAction(new CalloutAction({
text: "FAVORITE",
// tooltip: 'This is your custom action',
onClickCallback: function() {
CreateCustomNewQuickLink(renderCtx.CurrentItem.FileLeafRef, renderCtx.CurrentItem.FileRef);
}
}));
// Show the default document library actions
CalloutOnPostRenderTemplate(renderCtx, calloutActionMenu);
}
function CreateCustomNewQuickLink(title, url) {
var urlAddress = $(location).attr('protocol') + "//" + $(location).attr('host') + '/_Layouts/quicklinksdialogformTEST.aspx?Mode=Link' +
'&title=' + encodeURIComponent(title) +
'&url=' + encodeURIComponent(url);
ShowNewQuicklinkPopup(urlAddress, PageRefreshOnDialogClose);
}
Create a new add link page which is copied from "quicklinksdialogform.aspx". I add some javascript as below.
$(init)
function init() {
var args = new Object();
args = GetUrlParms();
if (args["title"] != undefined) {
$(".ms-long")[0].value = decodeURIComponent(args["title"]);
}
if (args["url"] != undefined) {
$(".ms-long")[1].value = decodeURIComponent(args["url"]);
}
}
function GetUrlParms() {
var args = new Object();
var query = location.search.substring(1);
var pairs = query.split("&");
for (var i = 0; i < pairs.length; i++) {
var pos = pairs[i].indexOf('=');
if (pos == -1) continue;
var argname = pairs[i].substring(0, pos);
var value = pairs[i].substring(pos + 1);
args[argname] = unescape(value);
}
return args;
}
It works like below

The Intern: Polling Until Element is Visible

Is there a way in Intern that I can poll until an element is visible? A lot of elements in my website are in the dom but are hidden, so every time I do a "find for" element X after it is supposed to appear, it fails because the element clearly breaks one of the visible attributes that selenium checks.
I've tried the helper function "pollUntil" but I can't seem to get that to work. Dojo seems to not like document.getElement*()
Helper Function that is passed into pollUntil
//this is a helper function for pollUntil
//first we want to find an element by class name and text
var elementVisibleAndText = function(elems, innerText){
elems = document.getElementsByClassName(elems);
//if we can't even find it, we return null
//but if we do find it, we want to return a
//not null element
if (!elems || elems.length == 0){
return null;
}
//now let's look at all of the elements found by
//in elems, and see if the innerHTML matches. If it
//does then we want to return that it was found
var each;
for(each in elems){
if(elems[each].innerHTML == innerText)
return (elems[each].offsetWidth > 0 && elems[each].offsetHeight > 0) ? elems[each] : null;
}
//else return null if nothing is found in the elements
return null;
};
Check out https://theintern.github.io/leadfoot/pollUntil.html. Intern uses leadfoot - so you should have access to this functionality.
var Command = require('leadfoot/Command');
var pollUntil = require('leadfoot/helpers/pollUntil');
new Command(session)
.get('http://example.com')
.then(pollUntil('return document.getElementById("a");', 1000))
.then(function (elementA) {
// element was found
}, function (error) {
// element was not found
});
To use the function within one of your tests - you would import it using the following path:
'intern/dojo/node!leadfoot/helpers/pollUntil'
I run into this issue all the time and we used the pollUntil functionality of intern to write a few helper utilities. In our tests we use something like .then(pollUntil(util.element_visible_by_class(), ['toast_notification'], 22000))
In a separate util.js file we have
/**
* Our shared utility for unit testing
*/
define([
'intern!object',
'intern/chai!assert',
'require',
'intern/dojo/node!leadfoot/helpers/pollUntil'
], function (registerSuite, assert, require, util, pollUntil) {
return {
element_visible_by_class: function(elem) {
return function(elem) {
elem = document.getElementsByClassName(elem);
if (!elem || elem.length == 0) { return null; }
elem = elem[0];
return (elem.offsetWidth > 0 && elem.offsetHeight > 0) ? elem : null;
}
},
element_visible_by_id: function(elem) {
return function(elem) {
elem = document.getElementById(elem);
if (!elem) { return null; }
return (elem.offsetWidth > 0 && elem.offsetHeight > 0) ? elem : null;
}
},
element_hidden_by_id: function(elem) {
return function(elem) {
elem = document.getElementById(elem);
if (!elem) { return null; }
return (elem.offsetWidth > 0 && elem.offsetHeight > 0) ? null : elem;
}
},
element_hidden_by_class: function(elem) {
return function(elem) {
elem = document.getElementsByClassName(elem);
if (!elem || elem.length == 0) { return null; }
elem = elem[0];
return (elem.offsetWidth > 0 && elem.offsetHeight > 0) ? null : elem;
}
},
}
})

Adding custom object to function

I'm making a mini JavaScript library and I am trying to allow people to add custom functions.
The current syntax is:
$$.custom('alert', function(){alert(this._string)});
To trigger the alert you would use the following:
$$.string("Hi").alert();
The issue is that this._string is supposed to return the string between () (it does for the normal functions) but instead it is returning undefined.
This is the code I use for the setup of the $$ object:
var g = function (a) {
this._string = typeof a == "string" ? a : "undefined"
},
NumberPro = function (a) {
this._number = typeof a == "number" ? a : "undefined"
},
$$ = {
string: function (a) {
return new g(a)
},
number: function (a) {
return new NumberPro(a)
},
syntax: {
off: function () {
for (var j in k) {
String.prototype[j] = String.prototype[j] || k[j];
};
for (var j in l) {
Number.prototype[j] = Number.prototype[j] || l[j];
};
type = 'prototype';
},
on: function () {
for (var j in l) {
NumberPro.prototype[j] = NumberPro.prototype[j] || l[j]
}
for (var j in k) {
g.prototype[j] = g.prototype[j] || k[j]
}
type = '';
}
},
usePrototype: function (a) {
$$.syntax.off();
a();
$$.syntax.on();
},
custom: function(name, f){
k[name] = f();
for (var j in k) {
g.prototype[j] = g.prototype[j] || k[j]
}
type = '';
}
},
type = '',
Methods = $$;
In the "custom", function...in k[name] = f(), the k is the object which the rest of the functions are stored in. I run a for loop to give each of them the $$.string object.
What I want to do is be able to add this._string to the function submitted in the custom alert function. I'm thinking this could be possible but I can't seem to get this to work. I hope I gave enough code so I can get a good answer. I though my way should work since in the custom function I'm running the for again to give the added function the $$ object too so this._string should be retrieving the string.
Thanks in advance.

Resources