Am trying to use the before() at TestCafe Fixture level.
My Goal is : Create Before() at fixture level, and this contains login Page scripts. So my plan is to run before() method before all other tests. I have 3 groups of code
1) Before() -- login code.
2) test1() -- sample code-1
3) test2() -- sample code-2
My requirement is: once the login is succeeded then test1(), test2() should use the same login which is defined in before(). Can you please help me here,
note: i tried using Testcafe-Live but did not succeed.
my test scenarios are: Before the test login method should be executed one time before executing test1 and test2. Also, the browser window should not close after each test
Similar question: How to do 'beforeEach' only at Fixture level and not for each test under that fixture
You could achieve this by using .beforeEach() on the Fixture and then using 'preserve url' option on the UserRole: TestCafe's documentation explains it here: https://devexpress.github.io/testcafe/documentation/test-api/authentication/user-roles.html#optionspreserveurl
Related
I'm trying to check which browser we're running tests on, and then skip a test/fixture based on the result (as mentioned in this TestCafe Issue).
import { t } from 'testcafe';
fixture `test`
.page('https://testcafe.devexpress.com')
if (t.browser.name.includes('Chrome')) {
test('is Chrome?', async () => {
console.log(t.browser.name);
await t.expect(t.browser.name.includes('Chrome').ok();
});
} else {
test.skip('is Chrome?')
};
Results in...
ERROR Cannot prepare tests due to an error.
Cannot implicitly resolve the test run in the context of which the test controller action should be executed. Use test function's 't' argument instead.
Is there any way I can call the testObject (t) outside of the test?
I don't have a solution to exactly your question. But I think it's better to do it slightly differently, so the outcome will be the same, but the means to achieve it will differ a bit. Let me explain.
Wrapping test cases in if statements is, in my opinion, not a good idea. It mostly clutters test files so you don't only see test or fixture at the left side, but also if statements that make you stop when reading such files. It presents more complexity when you just want to scan a test file quickly from top to bottom.
The solution could be you introduce meta data to your test cases (could work well with fixtures as well).
test
.meta({
author: 'pavelsaman',
creationDate: '16/12/2020',
browser: 'chrome'
})
('Test for Chrome', async t => {
// test steps
});
Then you can execute only tests for Chrome like so:
$ testcafe --test-meta browser=chrome chrome
That's very much the same as what you wanted to achieve with the condition, but the code is a bit more readable.
In case you want to execute tests for both chrome and firefox, you can execute more commands:
$ testcafe --test-meta browser=chrome chrome
$ testcafe --test-meta browser=firefox firefox
or:
$ testcafe --test-meta browser=chrome chrome && testcafe --test-meta browser=firefox firefox
If your tests are in a pipeline, it would probably be done in two steps.
The better solution, as mentioned in one of the comments in this question is to use the runner object in run your tests instead of the command line. Instead of passing the browser(s) as a CLI argument, you would pass it as an optional argument to a top-level script.
You would then read the browser variable from either the script parameter or the .testcaferc.json file.
You would need to tag all tests/fixtures with the browser(s) they apply to using meta data.
You then use the Runner.filter method to add a delegate that returns true if the browser in the meta data is equal to the browser variable in the top level script
var runner = testcafe.createRunner();
var browser = process.env.npm_package_config_browser || require("./testcaferc.json").browser;
var runner.filter((testName, fixtureName, fixturePath, testMeta, fixtureMeta) => {
return fixtureMeta.browser === browser || testMeta.browser === browser ;
}
I am trying to implement a fixture with multiple tests where all depend on each other
Therefore I want to clean the Database and perform login only one time from the Fixture.before Method
So it will look like this:
fixture `testProject`.page(baseUrl)
.before(async t => {
await loginPM.login()
await base.clearDB()
})
.beforeEach(async t => {
// some steps before each test
})
test 1
test 2
test 3
This scenario throws the following exception:
Error in fixture.before hook - Cannot implicitly resolve the test run in the context of which the test controller action should be executed. Use test function's 't' argument instead
Any ideas why testcafe not support calling functions from a Fixture.before Method
The fixture.before hook runs between tests and doesn't have access to the tested page. Please refer to the following help topic for details on its use: Fixture.before Method. If you need to execute test actions (click, typeText, etc) once per fixture before you start all tests, see this module: testcafe-once-hook module. Here is an example of how to use it: https://github.com/AlexKamaev/testcafe-once-hook-example.
I'm creating automated tests in Protractor for our site.
you have to login first in order to do anything on the site.
my problem is that for specific test (spec) - I can (have) to add 'login' - currently located in Page Object page.
the problem is that when creating a sanity test that uses multiple tests (using 'Suite') - I currently have to login for every specific test and then logout at the end so the next test will work properly (since it login at first).
what is the right way to do it?
on one hand I want that every test will work on its own (login at first) - but on the other hand - when using it in sanity test- I want to login and logout only once during the sanity test.
this is the suite part from the conf.js file:
suites:{
sanity: ['*/AccountSettingsTest.js','*/createApptest.js','*/openSourcePageTest.js','*/whatsNewTest.js']
},
specs: ['*/AccountSettingsTest.js'],
This is how I currently use the login:
var LoginPage = require('../global/LoginPage');
...
var login = new LoginPage();
...
login.clickLogin();
Thanks.
I'm afraid there is no beforeSuite() and afterSuite() if this is what you are asking about.
One thing that might work for you is to put the "logging in" part into onPrepare():
onPrepare: function () {
browser.get("myurl");
return loginPage.login(username, password); // login may also return a promise
},
In codeception acceptance testing, how to run/write same test case for many different set of inputs.
Here is my sample acceptance test (I am using page object oncept)
loginCept.php code
$I = new AcceptanceTester($scenario);
$I->wantTo('perform actions and see result');
$I->login($I,$m);
Acceptance.php file
class Acceptance extends \Codeception\Module
{
public function login($I)
{
$I->amOnPage(login::$loginIndex);
$I->wait(2);
$I->fillField(login::$userName,"test#gmail.com");
$I->fillField(login::$password,"test");
$I->click(login::$submitButton);
$I->see(login::$assertionWelcome);
$I->wait(2);
$I->click(login::$logoutLink);
}
}
How do I run same login with multiple set of inputs in acceptance test.
However, I have tried passing inputs in an array by calling the test case in for loop by passing array values as input parameter. In acceptance.php, multiple set of inputs can be passed using if loop.
This runs the test as only 1 test case with different assertions.
But, it runs the test case until it fails for any inputs/assertion. If it fails for any of the assertions, then test case stops executing further & says test case failed.
You can pass parameters through to your login function just as you would with any php function:
loginCept.php code
$I = new AcceptanceTester($scenario);
$I->wantTo('perform actions and see result');
$I->login($I,"test#gmail.com","test");
Acceptance.php file
class Acceptance extends \Codeception\Module
{
public function login($I,$username,$password)
{
$I->amOnPage(login::$loginIndex);
$I->wait(2);
$I->fillField(login::$userName,$username);
$I->fillField(login::$password,$password);
$I->click(login::$submitButton);
$I->see(login::$assertionWelcome);
$I->wait(2);
$I->click(login::$logoutLink);
}
}
You'd then want to create a separate cept for each aspect of login that you are looking to test.
Edit:
What you're looking for in relation to one test running through a number of assertions, this breaks the conventions of automated testing. Each test (or cept in this case) should only ever test one aspect. For instance in logging in, you might have one for invalid username, invalid password, too many attempts, etc... Then when/if one test fails, you as the developer knows exactly what aspect has failed and which continue to pass. If all the aspects are wrapped up in one test, then you as the developer don't know the full picture until you start to debug.
I have:
#OnApplicationStart
public class SomeClass {
.. doJob() ...
}
How I can test it in my Unit Test that doJob() actually launched when application started?
I would argue that this is not a unit test, but an integration test.
You can test your Job, by simply calling it using the syntax new MyJob().now();, but as you are looking to test the #OnApplicationStart function, the you would be better off doing this as a Selenium test, and checking the data that you expect to be made available from the bootstrap job is present.