I'm fairly new to Jasmine, and I'm using Protractor with page object. Here's the page object as it appears, complete with function called by the spec:
'use strict';
module.exports = {
structure: {
cliButton: element(by.id('cliSubmit')),
cliInput: element(by.id('commandLineInterface')),
casDrawButton: element(by.id('casdrawTrigger')),
benzeneIcon: element(by.id('cdBenzene')),
casDrawCanvas: element(by.id('cdCanvasContainer')),
saveUploadButton: element(by.id('cdOK')),
lastCommandResponse: element(by.id('commandResponse3')),
myFilesLink: element(by.id('my-stn-toggle')),
structuresLink: element(by.id('structureOptionsToggle')),
firstStructureName: element(by.id('structureNameLabel-0')),
returnHome: element(by.className('return-link')),
importStructure: element(by.id('importStructure')),
importBrowse: element(by.id('structureImportBrowse')),
importOK: element(by.id('structureImportModalOk')),
editStructureName: element(by.id('editStructureNameSave-0')),
structureDateTime: element(by.id('structureDate-0')),
structureSnippet: element(by.id('structureImage-0')),
firstEditButton: element(by.id('editStructure-0')),
firstUploadButton: element(by.id('uploadStructure-0')),
firstActionsButton: element(by.id('scriptActions-0')),
firstDeleteButton: element(by.id('confirmDelete-0')),
selectAll: element(by.id('selectAll')),
deleteAll: element(by.id('deleteStructures')),
selectCheckboxes: element(by.xpath("//*[contains(#id,'selectStructure')]"))
},
casDrawSteps: function () {
var structure = this.structure;
var today = new Date();
var year = today.getFullYear();
structure.cliInput.sendKeys('fil reg');
structure.cliButton.click();
structure.casDrawButton.click();
browser.sleep(6000);
structure.benzeneIcon.isEnabled();
structure.casDrawCanvas.isEnabled();
structure.benzeneIcon.click();
structure.casDrawCanvas.click();
structure.saveUploadButton.click();
structure.cliButton.isEnabled();
browser.sleep(6000);
expect(structure.lastCommandResponse.getText()).toContain('STRUCTURE UPLOADED');
structure.myFilesLink.click();
structure.structuresLink.click();
expect(structure.firstStructureName.getText()).toMatch(year + '_' + /\d*/ + '_Structure');
structure.returnHome.click();
structure.cliButton.isEnabled()
},
};
The problem is that the toMatch after the getText is not matching the regex, and according to all regex references I can find, it should. I have jasmine-matchers installed, so I'm uncertain why this is happening. Here's the stack I receive when I run the spec with this function:
Failures:
1) Protractor STNext Smoke Test - Structure: CASDraw creates a structure in CasDraw and verifies the response in Messenger
Message:
Expected '2017_0013_Structure' to match '2017_/\d*/_Structure'.
Stack:
Error: Failed expectation
at Object.casDrawSteps (/home/heb29/Desktop/casnc/repos/stn-kraken-qa/spec/pages/structure_page.js:50:56)
at UserContext.<anonymous> (/home/heb29/Desktop/casnc/repos/stn-kraken-qa/spec/smoke_spec.js:93:23)
at /usr/local/lib/node_modules/protractor/node_modules/jasminewd2/index.js:112:25
at new ManagedPromise (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:1067:7)
at ControlFlow.promise (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:2396:12)
at schedulerExecute (/usr/local/lib/node_modules/protractor/node_modules/jasminewd2/index.js:95:18)
at TaskQueue.execute_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:2970:14)
at TaskQueue.executeNext_ (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:2953:27)
at asyncRun (/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:2860:25)
What am I missing?
You need to concatenate regular expressions and regular strings correctly:
var text = structure.firstStructureName.getText();
expect(text).toMatch(year + /_\d*_Structure/.source);
Related
I'm trying make a test to my API server and I don't get test result no pass.
My code:
var data = JSON.parse(responseBody);
var days = data["days"];
var total_distance = 0;
days.forEach(function(value,index,array){
total_distance = total_distance + value["distance"];
});
pm.test("Distance data"),function(){
pm.expect(data["total_distance"].to.equal(total_distance));
}
This script never returns no pass. What is my error?
The syntax for your test is incorrect. You have a closing parentheses after pm.test("Distance data" which should actually be the last character on the last line.
Try:
pm.test("Distance data", function () {
pm.expect(data["total_distance"].to.equal(total_distance));
});
I'm been running into weird issues with regex and Typescript in which I'm trying to have my expression replace the value of test minus the first instance if followed by test. In other words, replace the first two lines that have test but for the third line below, replace only the second value of test.
[test]
[test].[db]
[test].[test]
Where it should look like:
[newvalue]
[newvalue].[db]
[test].[newvalue]
I've come up with lots of variations but this is the one that I thought was simple enough to solve it and regex101 can confirm this works:
\[(\w+)\](?!\.\[test\])
But when using Typescript (custom task in VSTS build), it actually replaces the values like this:
[newvalue]
[newvalue].[db]
[newvalue].[test]
Update: It looks like a regex like (test)(?!.test) breaks when changing the use cases removing the square brackets, which makes me think this might be somewhere in the code. Could the problem be with the index that the value is replaced at?
Some of the code in Typescript that is calling this:
var filePattern = tl.getInput("filePattern", true);
var tokenRegex = tl.getInput("tokenRegex", true);
for (var i = 0; i < files.length; i++) {
var file = files[i];
console.info(`Starting regex replacement in [${file}]`);
var contents = fs.readFileSync(file).toString();
var reg = new RegExp(tokenRegex, "g");
// loop through each match
var match: RegExpExecArray;
// keep a separate var for the contents so that the regex index doesn't get messed up
// by replacing items underneath it
var newContents = contents;
while((match = reg.exec(contents)) !== null) {
var vName = match[1];
// find the variable value in the environment
var vValue = tl.getVariable(vName);
if (typeof vValue === 'undefined') {
tl.warning(`Token [${vName}] does not have an environment value`);
} else {
newContents = newContents.replace(match[0], vValue);
console.info(`Replaced token [${vName }]`);
}
}
}
Full code is for the task I'm using this with: https://github.com/colindembovsky/cols-agent-tasks/blob/master/Tasks/ReplaceTokens/replaceTokens.ts
For me this regex is working like you are expecting:
\[(test)\](?!\.\[test\])
with a Typescript code like that
myString.replace(/\[(test)\](?!\.\[test\])/g, "[newvalue]");
Instead, the regex you are using should replace also the [db] part.
I've tried with this code:
class Greeter {
myString1: string;
myString2: string;
myString3: string;
greeting: string;
constructor(str1: string, str2: string, str3: string) {
this.myString1 = str1.replace(/\[(test)\](?!\.\[test\])/g, "[newvalue]");
this.myString2 = str2.replace(/\[(test)\](?!\.\[test\])/g, "[newvalue]");
this.myString3 = str3.replace(/\[(test)\](?!\.\[test\])/g, "[newvalue]");
this.greeting = this.myString1 + "\n" + this.myString2 + "\n" + this.myString3;
}
greet() {
return "Hello, these are your replacements:\n" + this.greeting;
}
}
let greeter = new Greeter("[test]", "[test].[db]", "[test].[test]");
let button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function() {
alert(greeter.greet());
}
document.body.appendChild(button);
Online playground here.
I have a changelog file formatted using Github's markdown.
Initially I used inline links for every link I needed to add, that is:
This is some [example](http://www.stackoverflow.com) line of text.
Over time, as the file grew in size, it became a bit messy due mainly to this way of inserting links.
I'd like to convert all links from inline to reference (see description of each), that is convert the above line to this:
This is some [example][1] line of text.
[1]: http://www.stackoverflow.com
Since the file is rather large and contains many inline links, I was wondering if there is some automated way to do this. I use Sublime Text 3 to edit, but I couldn't find a suitable package for this task. Perhaps some clever regex?
That's a great requirement!
I've just created a new Node.js program (I know it's not a GUI but seems something more people would like the capability of) to do this on GitHub.
Here's also the code:
// node main.js test.md result.md
var fs = require('fs')
fs.readFile(process.argv[2], 'utf8', function (err, markdown) {
if (err) {
return console.log(err);
}
var counter = 1;
var matches = {};
var matcher = /\[.*?\]\((.*?)\)/g;
while (match = matcher.exec(markdown)) {
if (!matches[match[1]]) matches[match[1]] = counter++;
}
console.log(matches);
Object.keys(matches).forEach(function(url) {
var r = new RegExp("(\\[.*?\\])\\(" + url + "\\)", "g");
markdown = markdown.replace(r, "$1[" + matches[url] + "]");
markdown += "\n[" + matches[url] + "]: " + url;
});
fs.writeFile(process.argv[3], markdown, 'utf8', function (err) {
if (err) return console.log(err);
});
});
Save this as mdrelink.py in your Packages folder, and you can then run it with
view.run_command('mdrelink');
from within the command console.
I think I got the order thingy right – reversing is necessary because otherwise it would mess up the already cached indexes of next items. It should also automatically skip already used link numbers. My first Python and my first Sublime plugin, so please be gentle with me.
import sublime, sublime_plugin
class mdrelinkCommand(sublime_plugin.TextCommand):
def run(self, edit):
oldlinks = []
self.view.find_all("^\s*(\[\d+\]):", sublime.IGNORECASE, "\\1", oldlinks)
newlinkpos = self.view.find_all("\[.+?\](\(.+?\))")
orgtext = []
self.view.find_all("(\[.+?\])\(.+?\)", sublime.IGNORECASE, "\\1", orgtext)
orglink = []
self.view.find_all("\[.+?\]\((.+?)\)", sublime.IGNORECASE, "\\1", orglink)
orglink.reverse()
self.view.insert(edit, self.view.size(), '\n\n')
counter = 1
newnumbers = []
for r in newlinkpos:
while '['+str(counter)+']' in oldlinks:
counter += 1
oldlinks.append('['+str(counter)+']')
line = '[' + str(counter)+']: '+ orglink.pop() + '\n'
newnumbers.append(' ['+str(counter)+']')
self.view.insert(edit, self.view.size(), line)
for r in reversed(newlinkpos):
self.view.replace(edit, r, orgtext.pop()+newnumbers.pop())
Came across this question thanks to Google. Maybe this can help others:
My answer isn't Sublime specific, but if you're using JavaScript (Node) already, I'd use a Markdown parser and CST transformer like remark.
For example, to transform all the inline links in README.md to numerically-ascending reference-style links, you could run the following at your project's root:
npm install --save-dev remark-cli remark-renumber-references
npx remark --no-stdout --output --use renumber-references README.md
Or, if you want reference-style links derived from the source uri:
npm install --save-dev remark-cli remark-defsplit
npx remark --no-stdout --output --use defsplit README.md
Hopefully this info helps people like me not waste a whole day hacking together some horrendously unreliable regexp-based solution to this :)
extending #bjfletcher's answer, below is the code that considers any existing reference links.
Link to GitHub gist.
// node filename.js ReadMe.md RefLinks.md
import * as fs from 'fs'
fs.readFile(process.argv[2], 'utf8', function (err, mainMarkdown) {
if (err) {
return console.log(err);
}
let newMarkdown = existingRefLinks(mainMarkdown);
var counter = 1;
var matches = {};
var matcher = /\[.*?\]\((.*?)\)/g
let match;
while (match = matcher.exec(newMarkdown)) {
if (!matches[match[1]]) matches[match[1]] = counter++;
}
console.log(matches);
Object.keys(matches).forEach(function (url) {
var r = new RegExp("(\\[.*?\\])\\(" + url + "\\)", "g");
newMarkdown = newMarkdown.replace(r, "$1[" + matches[url] + "]");
newMarkdown += "\n[" + matches[url] + "]: " + url;
});
fs.writeFile(process.argv[3], newMarkdown, 'utf8', function (err) {
if (err) return console.log(err);
});
});
function existingRefLinks(markdown) {
let refLinks = {}, match;
const matcher = /\[(\d)]:\s(.*)/g; // /\[.*?\]\((.*?)\)/g
while (match = matcher.exec(markdown)) {
if (!refLinks[match[1]]) refLinks[match[1]] = match[2];
}
markdown = markdown.replaceAll(matcher, "")
Object.keys(refLinks).forEach(function (int) {
markdown = markdown.replace("][" + int + "]", "](" + refLinks[int] + ")");
});
return markdown
}
Note that I prefer using #Xunnamius's answer:
npm install --save-dev remark-reference-links remark-cli
npx remark README.md -o --use reference-links
In the findQuery function of the Ember local storage adapter, I'm confused about this line containing "[Object RegExp]". What does it mean?
if (Object.prototype.toString.call(test) == '[object RegExp]') {
push = test.test(record[property]);
} else {
push = record[property] === test;
}
[Object RegExp] is the string representation (toString()) of a regular expression object in Javascript.
That part of the code checks if the query is a regular expression. If so, it runs the expression object's test() on the property, otherwise does a strict === comparison.
Try running this in a console:
var test = /a.*?nice regex/;
var string = "Is this a very nice regex?";
console.log( Object.prototype.toString.call(test) );
console.log( test.test(string) );
I've had a bug that has been bugging me for days. I'm pretty new to Node and the Jade templating system so bear with me: I'm looking to add stylesheets in the following way:
App.js (Express):
app.get('/', loadUser, function(req, res) {
var User = req.user;
// console.log(User.groups[2]);
// var groups = User.groups.split(',');
// OK DUh. This only gets called when the client has the script Socket.IO
// and client runs socket.connect()
getMessages(User, function(messages) {
var locals = {
scripts: [
'https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js',
'index.js'
],
stylesheets: [
'index.css'
],
user : User,
messages: messages
};
console.log('ok');
res.render('app.jade', {locals : locals});
});
});
In layout.jade (which is executed with app.jade) I have:
!!! 5
html
head
title UI
link(rel='stylesheet', href = 'stylesheets/reset.css')
link(rel='stylesheet', href = 'stylesheets/layout.css')
- var stylesheets = stylesheets || [];
#{stylesheets}
- each stylesheet in stylesheets
- if(stylesheet.indexOf('http') >= 0)
link(rel='stylesheet', href = stylesheet)
- else
link(rel='stylesheet', href = "stylesheets/"+stylesheet )
Plus more... I keep running into the same error:
9. ' - if(stylesheet.indexOf(\'http') >= 0)'
Object function () {
var o = {}, i, l = this.length, r = [];
for(i=0; i
for(i in o) r.push(o[i]);
return r;
} has no method 'indexOf'
Now.. the gotcha is that this exact template works in another application that passes in the exact same variables: I would REALLY appreciate any suggestions you guys have on this thorny issue!
Thanks!
Matt Mueller
So here's your issue...
in this line:
res.render('app.jade', {locals : locals});
you are passing in locals ==> locals, which is a hash (ok, so I'm a PERL guy, I think JS calls them 'associative arrays')
So now inside your jade template we have the line:
- var stylesheets = stylesheets || [];
inside JADE, you have defined the variable "locals", but everything else is hidden under that, so the variable "stylesheets" is NOT defined (locals.stylesheets is defined instead). So this line of code sets the variable "stylesheets" to "[]"
So here's where I have to speculate. "indexOf" is a method of the Array object. Perhaps arrays constructed inside JADE don't have this method whereas arrays constructed in node.js DO have this method. Which would explain why you get an error trying to call "stylesheets.indexOf(...)"