unit testing for chrome api using jasmine - google-chrome-app

How can I test chrome.runtime.getManifest() using jasmine? Below is what i tried:
var manifestData = {"name": "Pearson App Chromebook Edition", "version": "0.0.1", "manifest_version": 2};
beforeEach(function() {
module(function ($provide) {
$provide.value('chrome.runtime', {
getManifest: function () {
return manifestData;
}
});
});
});
I am getting 'TypeError: chrome.runtime.getManifest is not a function' error.
Thanks in advance.

The thing that worked for me was:
chrome = {
runtime: {
getManifest: function(){}
}
};
spyOn(chrome.runtime, 'getManifest').and.returnValue(manifestData);
where manifestData is the mock of manifest.json

Related

After successfully deploying Next.js app on AWS Amplify, https://www.example.com/api/any-route showing below error in console

The app is deployed successfully but the API routes (/pages/api) are not working as expected, showing below error in the console.
Build is successful and deployed on aws-amplify, I have added environment variables correctly, don't know why this is happening?
Does aws-amplify doesn't support serverless functions writer inside /api folder??
{
"error": {
"message": "connect ECONNREFUSED 127.0.0.1:80",
"name": "Error",
"stack": "Error: connect ECONNREFUSED 127.0.0.1:80\n at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1148:16)",
"config": {
"url": "undefined/campaigns",
"method": "get",
"headers": {
"Accept": "application/json, text/plain, */*",
"User-Agent": "axios/0.21.4"
},
"auth": {},
"transformRequest": [null],
"transformResponse": [null],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"transitional": {
"silentJSONParsing": true,
"forcedJSONParsing": true,
"clarifyTimeoutError": false
}
},
"code": "ECONNREFUSED"
}
}
Here is the code
import axios from 'axios';
import Cors from 'cors';
import rateLimit from '../../../utils/rate-limit';
import initMiddleware from '../../../lib/init-middleware';
// Initialize the cors middleware
const cors = initMiddleware(
Cors({
methods: ['POST'],
origin: ['https://www.example.com', /\.example\.com$/],
})
);
const limiter = rateLimit({
interval: 60 * 1000, // 60 seconds
uniqueTokenPerInterval: 500, // Max 500 users per second
});
const handler = async (req, res) => {
await cors(req, res);
if (req.method === 'GET') {
try {
await limiter.check(res, 50, 'CACHE_TOKEN');
const { data } = await axios.get(`${process.env.BASE_URL}/campaigns`, {
auth: {
username: process.env.MAIL_SERVER_USERNAME,
password: process.env.MAIL_SERVER_PASSWORD,
},
});
return res.status(200).json(data);
} catch (error) {
return res.status(429).json({ error });
}
} else {
try {
await limiter.check(res, 10, 'CACHE_TOKEN'); // 10 requests per minute
return res.status(200).json('not allowed');
} catch (err) {
return res.status(429).json({ error: 'Rate limit exceeded' });
}
}
};
export default handler;
I figured out that environment variables are not getting reflected, so did some googling; found this solution and it worked for me.
Add your desired environment variable in the Amplify Console-like normal (steps)
Update (or create) your next.config.js file with the environment variable you added in the Amplify Console. E.g if you created an environment variable named MY_ENV_VAR in the console in step 1) above, then you would add the following:
module.exports = {
env: {
MY_ENV_VAR: process.env.MY_ENV_VAR
}
};
Now after your next build you will be able to reference your environment variable (process.env.MY_ENV_VAR) in your SSR lambdas!
Here is the link: Github
Ran into the same problem Amplify only supports NextJS 11 at the moment. If you go with the default settings it will use the latest NextJS 12 and /api routes wont work, they return a 503 with a cloudformation permission error.
Specify next 11.1.3 in your package.json
https://aws.amazon.com/about-aws/whats-new/2021/08/aws-amplify-hosting-support-next-js-version-11/
I also faced that problem. Amplify does not support v12 of next. Simply downgrade your next.js version in package.json to v1.1.3 and your routes will work as normal.
Best regrets.
Artem Meshkov

Cannot test a native Android app using codeceptJS

I have created a codeceptJS project by following the mobile testing setup steps located here: https://codecept.io/mobile/#setting-up
So far, I'm unable to test any apps via simulator; I instead get the following error:
1) login
I should be able to login with the correct username and password:
>> The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource <<
at Object.getErrorFromResponseBody (node_modules/webdriver/build/utils.js:189:12)
at NodeJSRequest._request (node_modules/webdriver/build/request/index.js:157:31)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
I have verified my appium config using appium-doctor, and there are no issues found.
My codecept.conf.js is as follows:
const path = require('path');
const { setHeadlessWhen } = require('#codeceptjs/configure');
// turn on headless mode when running with HEADLESS=true environment variable
// export HEADLESS=true && npx codeceptjs run
setHeadlessWhen(process.env.HEADLESS);
exports.config = {
tests: './*_test.js',
output: './output',
helpers: {
Appium: {
platform: 'Android',
device: 'emulator',
desiredCapabilities: {
avd: 'Pixel_5_API_28',
app: path.resolve('./sample_apps/Android.apk'),
appActivity: 'com.swaglabsmobileapp.MainActivity'
}
},
},
include: {
I: './steps_file.js'
},
bootstrap: null,
mocha: {},
name: 'appium-codecept-android-POC',
plugins: {
pauseOnFail: {},
retryFailedStep: {
enabled: true
},
tryTo: {
enabled: true
},
screenshotOnFail: {
enabled: true
}
}
}
And here's my package.json as created by codeceptjs init:
{
"name": "appium-codecept-android-POC",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"codeceptjs": "^3.0.7",
"webdriverio": "^7.9.0"
}
}
Finally, my test file is as follows:
Feature('login');
Scenario('I should be able to login with the correct username and password', ({ I }) => {
setTimeout(() => {
I.see('Username');
}, 3000);
I.click('//android.widget.EditText[#content-desc="test-Username"]');
I.fillField('//android.widget.EditText[#content-desc="test-Username"]', 'standard_user');
I.click('//android.widget.EditText[#content-desc="test-Password"]');
I.fillField('//android.widget.EditText[#content-desc="test-Password"]', 'secret_sauce');
I.click('//android.view.ViewGroup[#content-desc="test-LOGIN"]');
I.waitForElement('//android.view.ViewGroup[#content-desc="test-Cart drop zone"]/android.view.ViewGroup/android.widget.TextView', 3)
I.dontSeeElement('//android.view.ViewGroup[#content-desc="test-Error message"]/android.widget.TextView');
});
Scenario('I should not be able to login with an incorrect username or password', ({ I }) => {
setTimeout(() => {
I.see('Username');
}, 3000);
I.click('//android.widget.EditText[#content-desc="test-Username"]');
I.fillField('//android.widget.EditText[#content-desc="test-Username"]', 'bob');
I.click('//android.widget.EditText[#content-desc="test-Password"]');
I.fillField('//android.widget.EditText[#content-desc="test-Password"]', 'secret_sauce');
I.click('//android.view.ViewGroup[#content-desc="test-LOGIN"]');
I.waitForElement('//android.view.ViewGroup[#content-desc="test-Cart drop zone"]/android.view.ViewGroup/android.widget.TextView', 3)
I.dontSeeElement('//android.view.ViewGroup[#content-desc="test-Error message"]/android.widget.TextView');
});
Scenario('I should be able to see details', ({ I }) => {
// login
setTimeout(() => {
I.see('Username');
}, 3000);
I.click('//android.widget.EditText[#content-desc="test-Username"]');
I.fillField('//android.widget.EditText[#content-desc="test-Username"]', 'standard_user');
I.click('//android.widget.EditText[#content-desc="test-Password"]');
I.fillField('//android.widget.EditText[#content-desc="test-Password"]', 'secret_sauce');
I.click('//android.view.ViewGroup[#content-desc="test-LOGIN"]');
I.waitForElement('//android.view.ViewGroup[#content-desc="test-Cart drop zone"]/android.view.ViewGroup/android.widget.TextView', 3)
// should be able to click a label to see details
I.click('(//android.widget.TextView[#content-desc="test-Item title"])[2]');
I.seeElement('//android.view.ViewGroup[#content-desc="test-Description"]/android.widget.TextView[2]');
I.click('//android.view.ViewGroup[#content-desc="test-BACK TO PRODUCTS"]');
});
I'm at a loss here, as I haven't done anything except follow the setup instructions. Executing against ios works; it is only the android execution that fails. Appium is installed and running, env vars are set, etc. Any help would be appreciated, as this could be a deal breaker for me in terms of whether or not I can use codeceptjs. I love the project and really want to use it, but I must be able to test both ios and android native apps.
One final note: If anyone wants to try this config, the app I am using for the above test can be found here: https://github.com/saucelabs/sample-app-mobile/releases/download/2.7.1/Android.SauceLabs.Mobile.Sample.app.2.7.1.apk

Getting an ' instance.requestPaymentMethod is not a function' in Braintree's sample

I'm getting an instance.requestpaymentmethod is not a function when I was just following along the tutorial for custom-field integration found here:
https://developers.braintreepayments.com/start/tutorial-hosted-fields-node
The error happens when I click on the "Pay" button.
Did anyone solve this problem? My assumption is that the code isn't updated or the script sources changed somewhat. If anyone from Braintree can actually help, that'll be great.
Thanks!
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
I took a look at the example code snippet in the guide you shared and I was able to find the culprit. First off, the error you're getting is expected as the requestPaymentMethod method actually belongs to our Drop-In UI solution and the Hosted Fields JS library doesn't have such module. I informed our Documentation team to get that code example updated.
That being said, you can find a working example in our Hosted Fields guide. If you check the function (hostedFieldsErr, hostedFieldsInstance) callback function, you'll see that the payment nonce is created by the tokenize function of the hostedFieldsInstance.
I also ran into this issue today. Use the following code in <script> tag. It will work for you.
var form = document.querySelector('#hosted-fields-form');
var submit = document.querySelector('input[type="submit"]');
braintree.client.create({
authorization: '<YOUR_TOKENIZATION_KEY>'
}, function (clientErr, clientInstance) {
if (clientErr) {
console.error(clientErr);
return;
}
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {
'font-size': '14px'
},
'input.invalid': {
'color': 'red'
},
'input.valid': {
'color': 'green'
}
},
fields: {
number: {
selector: '#card-number',
placeholder: '4111 1111 1111 1111'
},
cvv: {
selector: '#cvv',
placeholder: '123'
},
expirationDate: {
selector: '#expiration-date',
placeholder: '10/2019'
}
}
}, function (hostedFieldsErr, hostedFieldsInstance) {
if (hostedFieldsErr) {
console.error(hostedFieldsErr);
return;
}
form.addEventListener('submit', function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (tokenizeErr, payload) {
if (tokenizeErr) {
console.error(tokenizeErr);
return;
}
console.log('Got a nonce: ' + payload.nonce);
$.ajax({
type: 'POST',
url: '<YOUR_API_URL>',
data: { 'paymentMethodNonce': payload.nonce }
}).done(function (result) {
hostedFieldsInstance.teardown(function (teardownErr) {
if (teardownErr) {
console.error('Could not tear down Drop-in UI!');
} else {
console.info('Drop-in UI has been torn down!');
$('#submit-button').remove();
}
});
if (result.success) {
$('#checkout-message').html('<h1>Success</h1><p>Your Drop-in UI is working! Check your sandbox Control Panel for your test transactions.</p><p>Refresh to try another transaction.</p>');
} else {
console.log(result);
$('#checkout-message').html('<h1>Error</h1><p>Check your console.</p>');
}
});
});
}, false);
});
});

Target [Illuminate\Contracts\Routing\ResponseFactory] is not instantiable

I am trying to return a response like this:
return response()->json(['name' => 'Abigail', 'state' => 'CA']);
however, I got error:
Target [Illuminate\Contracts\Routing\ResponseFactory] is not instantiable.
Any idea?
Here is my composer.json:
{
"name": "laravel/lumen",
"description": "The Laravel Lumen Framework.",
"keywords": [
"framework",
"laravel",
"lumen"
],
"license": "MIT",
"type": "project",
"require": {
"php": ">=5.5.9",
"laravel/lumen-framework": "5.2.*",
"vlucas/phpdotenv": "~2.2",
"generationtux/jwt-artisan": "^0.1.7",
"barryvdh/laravel-cors": "^0.8.0",
"neomerx/cors-illuminate": "^1.1",
"fenos/notifynder": "3.1.*",
"franzose/closure-table": "^4.1",
"mlntn/lumen-artisan-serve": "~1",
"guzzlehttp/guzzle": "~6.0",
"league/flysystem": " ~1.0",
"bugsnag/bugsnag-laravel": "^2.0"
},
"require-dev": {
"fzaninotto/faker": "~1.4",
"phpunit/phpunit": "~4.0"
},
"autoload": {
"psr-4": {
"App\\": "app/",
"GuzzleHttp\\": "/vendor/guzzlehttp/"
},
"classmap": [
"database/"
]
},
"autoload-dev": {
"classmap": [
"tests/",
"database/"
]
},
"config": {
"preferred-install": "dist"
}
}
I still get the error in 2020. Here's an updated version of the solution by #sunben:
In bootstrap/app.php, uncomment the following line
$app->register(App\Providers\AppServiceProvider::class);
Then in app\Providers\AppServiceProvider.php, update register method to add:
$this->app->singleton(\Illuminate\Contracts\Routing\ResponseFactory::class, function() {
return new \Laravel\Lumen\Http\ResponseFactory();
});
Might be late but found the solution.
In bootstrap/app.php, uncomment the following line
$app->register(App\Providers\AppServiceProvider::class);
Then in app\Providers\AppServiceProvider.php, update register method to add:
public function register()
{
$this->app->singleton('Illuminate\Contracts\Routing\ResponseFactory', function ($app) {
return new \Illuminate\Routing\ResponseFactory(
$app['Illuminate\Contracts\View\Factory'],
$app['Illuminate\Routing\Redirector']
);
});
}
The response helper may be used to conveniently generate other types of response instances. When the response helper is called without arguments, an implementation of the Laravel\Lumen\Http\ResponseFactory class is returned.
use Laravel\Lumen\Http\ResponseFactory;
Try like this
public function register() { $this->app->singleton(\Illuminate\Contracts\Routing\ResponseFactory::class, function() { return new \Laravel\Lumen\Http\ResponseFactory(); }); $this->app->bind(\Illuminate\Contracts\Routing\UrlGenerator::class, function ($app) { return new \Laravel\Lumen\Routing\UrlGenerator($app); }); }
call
use Tests\TestCase;
instead of
use PHPUnit\Framework\TestCase;
your function depends on another function, So you should extend like feature test and not unit tests.
Those who are still getting routing related error, just put the following line in your composer.json file and run the command composer update
"illuminate/routing": "^5.6"
composer update
and boom here we go, wish all things are working great now
https://stackoverflow.com/a/48678862/9751944
#sunben's answer worked for me but I added the following inside the register method
$this->app->bind(\Illuminate\Routing\RouteCollectionInterface::class, function ($app) { return new \Illuminate\Routing\RouteCollection; });

How to detect if API is down?

As I type this the fb:like button is down - the Facebook API health page is reporting errors
https://developers.facebook.com/live_status
I am sure it will be back soon, but how can I detect this?
The reason being; I wish to hide other elements on the page as it looks odd when you have a facebook feature & then the button is missing.
Get the JSON response from this site: https://www.facebook.com/feeds/api_status.php
For NodeJS:
You can use the https module that comes with Node: https://nodejs.org/api/https.html#https_https_request_options_callback
I was struggling with this on my Node.js server, but found a solution. I was trying to do an http request with no luck (kept getting an unsupported browser problem), but when I tried to do it with cURL, it worked just fine.
So I decided to pass a User-Agent in my header for my NodeJS request, since I was getting that unsupported browser problem:
var https = require("https");
var options = {
hostname: 'www.facebook.com',
port: 443,
path: '/feeds/api_status.php',
method: 'GET',
headers: {
"User-Agent": 'curl/7.43.0'
}
};
var req = https.request(options, function(res) {
res.on('data', function(d) {
process.stdout.write(d);
});
});
req.end();
req.on('error', function(e) {
console.error(e);
});
The api_status then prints out in your console as so:
{
"current": {
"health": 1,
"subject": "Facebook Platform is Healthy"
},
"push": {
"status": "Complete",
"updated": "2016-01-27T16:05:12-08:00",
"id": 61183893
}
}
You can do what you need with it. For example, if you want to use it to see if the Facebook API is healthy, you can do the following:
var facebookIsHealthy;
var req = https.request(options, function(res) {
res.on('data', function(d) {
// d is a buffer object
var bufferString = d.toString();
var bufferObject = JSON.parse(bufferString);
if(bufferObject.current.health === 1) {
facebookIsHealthy = true;
}
else {
facebookIsHealthy = false;
}
});
});
Hope this helps!