I am trying to get a hang of Test Cafe but currently I am stuck.
I have a webapp I want to test starting at the login and ending with a logout.
When I login with wrong credentials I display a DOM Element with the id = errorMsg.
With Test Cafe I want to check if the DOM Element is present or not.
This is my test script, the basic-page-model.js is a collection of all DOM elements ids used in the test.
import Page from './basic-page-model';
import { Selector } from 'testcafe';
fixture `Full Test Run of Main Features Role User`
.page `https://localhost:8443/login.jsp`;
const page = new Page();
const errorMessage= Selector('#errorMsg');
test('login test', async t => {
await t
.typeText(page.nameInput, 'user')
.typeText(page.passInput, 'user') //correct password -> password
.click(page.login)
.expect(errorMessage.exists).notOk();
});
It doesn't matter if the login will fail or not it always returns test passed.
Can somebody please point me in the right direction?
According to your test code, you have no #errorMsg DOM element in both cases: with correct and incorrect credentials. I created a simple example and it works well:
index.html (Error Message exists)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Error Message</title>
</head>
<body>
<div id="errorMsg">
<p>Error Message</p>
</div>
</body>
</html>
no-message.html (no Error Message)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>No Error Message</title>
</head>
<body>
</body>
</html>
test.js
import { Selector } from 'testcafe';
fixture `Error message`;
const errorMessage = Selector('#errorMsg').addCustomDOMProperties({
outerHtml: el => el.outerHtml
});
test
.page('localhost:8080/no-message')
('message should not exist', async t => {
await t
.expect(errorMessage.exists).notOk();
});
test
.page('localhost:8080')
('message should exist', async t => {
await t
.expect(errorMessage.exists).ok();
});
Result:
>testcafe chrome test.js
Running tests in:
- Chrome 83.0.4103.116 / Windows 10
Error message
√ message should not exist
√ message should exist
2 passed (0s)
You may have a wrong error message id in your test.
If the example above doesn't help, I suggest you update your question with a simple project.
Related
My code so far:
I called the api using fetch() and converted the data to JSON, but I am not getting the logic to do the count of the number of pets.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Petstrore API</title>
</head>
<body>
<label>Number of pets:</label><br>
<textarea id="result"></textarea>
<script>
const petStore_url = 'https://petstore.swagger.io/v2/pet/findByStatus?status=available';
async function getPetCount() {
const response = await fetch(petStore_url);
const data = await response.json(); //Converting response to JSON
console.log(data);
}
getPetCount();
</script>
</body>
</html>
Since it returns an array, you should be able to do Array.length, or in your case data.length to get the count of first level objects (pets).
While trying to use Twilio TaskRouter JS SDK on Vue JS, that you have load through CDN.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script src="https://sdk.twilio.com/js/taskrouter/v1.21/taskrouter.min.js" integrity="sha384-5fq+0qjayReAreRyHy38VpD3Gr9R2OYIzonwIkoGI4M9dhfKW6RWeRnZjfwSrpN8" crossorigin="anonymous"></script>
</body>
</html>
I want to init my worker like this:
export const initWorker = (token) => {
return new Twilio.TaskRouter.Worker(token);
}
but it's giving me this error: 'Twilio' is not defined. but it's actually working and returning the Worker object. is there way to ignore or to say Vue js that I'm expecting Twilio?
Found a fix, you have to tell eslint that you'll have this as global, there are two ways to go:
add this before your variable call:
/* global Twilio */
or edit your eslint config:
'globals': {
'Twilio': 'readable'
},
Express isn't passing my variable into the EJS template.
I've read this, this, this, this, this, and this. The most promising one is this... no dice.
I didn't find something that worked from these.
I've tried removing spaces from <%- loggedIn %> to no spaces <%-loggedIn%>, making the object in Express simpleres.render('test', {loggedIn: "Simple"}). I've triedapp.set("view options", { delimiter: "?" });` like I saw in the EJS/Express wiki, no dice.
// /backend/router.js
const app = express();
app.set("view engine", "ejs");
app.set("view options", { delimiter: "?" });
app.use("/", (req, res) => {
res.render("test", { loggedIn: "Test" });
});
// /views/test.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title> </title>
</head>
<body>
User logged in: <%- loggedIn %>
</body>
</html>
I expected "User logged in: Test" to show when I went to localhost:8035. Instead I got ReferenceError, loggedIn not defined.
So I did know that when an Express server runs, it caches the routes file. New changes to the routes file in the editor doesn't reflect until restart. I knew this, but when I restarted before, I must've passed in an incorrect variable when I restarted the server. I restarted the server again and the error's no longer there.
But now it just shows User logged in: <%= loggedIn %>...
I have set up a very simple functions.html which launches a likewise simple dialog that only registers Office.initialize with a console log. If left open too long I get a large error in the console and the dialog becomes unclosable except by refresh.
Is this a known issue or is there something i need to be doing differently?
dialog.html
<!DOCTYPE html>
<html lang="en" style="height: 100%">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
<title>React App</title>
<script>
Office.initialize = x => {
console.log('initialized')
}
</script>
</head>
<body style="height: 100%">
yo stuff
</body>
</html>
my js looks like this
export const showSmsModal = () => {
officeCtx().ui.displayDialogAsync(`${window.location.origin}/test.html`, {displayInIframe: true, height: 40, width: 40}, ({ value: dialog }) => {
console.log(dialog)
return dialog
})
}
and part of the error i get is the following:
Uncaught Exception in t(t){var o=e.call(this,t)||this;return
o._warnDeprecations({onLayerMounted:"onLayerDidMount"}),o.props.hostId&&(u[o.props.hostId]||(u[o.props.hostId]=[]),u[o.props.hostId].push.componentWillUnmount():
TypeError: Cannot read property 'extension' of null
at Object.o [as default] (https://r4.res.office365.com/owa/prem/16.2478.1.2588899/scripts/owa.clientnext.extensibility.js:2:16883)
at e.refCallback (https://r4.res.office365.com/owa/prem/16.2478.1.2588899/scripts/owa.clientnext.extensibility.js:7:15203)
at r (https://r4.res.office365.com/owa/prem/16.2478.1.2588899/scripts/owa.clientnext.application.js:94:3330)
at Object.a.detachRefs (https://r4.res.office365.com/owa/prem/16.2478.1.2588899/scripts/owa.clientnext.application.js:94:3783)
It appears that the hidden iframe which is used to call the showDialog function goes away and the dialog iframe is unable to communicate with it and interval console logs i set up seem to stop from it.
I would expect it to close both iframes.
I am stymied by this issue. For some reason the Angular routing is not working at all. I simply get a blank screen. All of the modules are loading, there is no error in the console, and if I enter Angular in the console, it works. Yet, I get a blank screen.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>QuickCalcs</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="css/main.css" rel="stylesheet">
<link rel="stylesheet" href="css/ng-animation.css">
<script src="js/jquery-1.11.1.min.js"></script>
<script src="js/angular.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/angular-route.min.js"></script>
<script src="js/angular-animate.min.js"></script>
<script src="js/app.js"></script>
<script src="js/factories.js"></script>
<script src="controllers/qcController.js"></script>
</head>
<body ng-app="qc">
<div ng-view></div>
</body>
</html>
-----------------------------
app.js file is:
-----------------------------
var qc = angular.module('qc', [
'ngRoute',
'ngAnimate',
'ngResource'
]);
qc.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'views/home.html',
controller: 'qcController'
}).
when('/home', {
templateUrl: 'views/home.html',
controller: 'qcController'
}).
when('/results', {
templateUrl: 'views/results.html',
controller: 'qcController'
}).
otherwise({
redirectTo: 'views/home.html'
});
}]);
-----------------------------
Directory structure is:
-----------------------------
qc
/js
app.js
/views
home.html
results.html
/controllers
qccontroller.js
You must link your page to the application module
in the html tag like this:
< html lang="en" ng-app="qc" />