On clicking a button, I should get the location settings popup to accept/cancel the location permission, but in cypress test runner, on clicking the button, it shows permission denied.
I have checked the browser permission also, that didn't work.
Referred this:
https://github.com/kamranayub/cypress-browser-permissions/blob/master/cypress/integration/notifications.test.js
Added below permissions in cypress.json file:
"browserPermissions": {
"notifications": "allow",
"geolocation": "allow",
}
Nothing seems to work!
CAVEAT: This worked for Chrome not for Firefox, I didn't try Edge. I have no idea whether this will work for anyone else, but as it did for me after I looked at this very thread, I'll add it in.
I am using the more recent Cypress config format and I found that adding the browserPermissions object to the first level env variable inside the config didn't work. It does, however, appear to work if I instead add the configuration inside the e2e object:
const { defineConfig } = require('cypress');
const { cypressBrowserPermissionsPlugin } = require('cypress-browser-permissions');
module.exports = defineConfig({
// ...other configs
e2e: {
setupNodeEvents(on, config) {
config = cypressBrowserPermissionsPlugin(on, config);
config.env.browserPermissions = {
geolocation: 'allow',
};
return config;
}
}
});
NOTE: I had to stop and restart the Cypress process (restarting the browser window, as it does on save, isn't sufficient). I will also say that once I did this settings were forced and unchangeable in the browser settings page(s). So I'm not entirely sure this is how you should go about it, just that I now do not get prompted for geolocation permissions.
Related
I am trying to connect with an iOS device to the Firebase Auth and RealTime Database Emulator.
The thing is, I can connect and use emulator through Firebase Admin using NodeJS on local machine (trough http://localhost:9000?ns=my-project).
Also I am able to connect with an iOS device to the remote Firebase server... But locally it doesn't work. It throws bunch of random errors, like this (when I try to complete registration/authentication):
Error Domain=NSURLErrorDomain Code=-1004 "Could not connect to the
server." NSLocalizedDescription=Could not connect to the server.,
NSErrorFailingURLStringKey=http://192.168.1.3:9099/www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=myKeyGoesHere
and
Optional(Error Domain=com.firebase.core Code=1 "Unable to get latest
value for query FQuerySpec (path: /news, params: { }), client offline
with no active listeners and no matching disk cache entries"
Here is firebase.json:
{
"database": {
"rules": "database.rules.json"
},
"emulators": {
"auth": {
"port": 9099
},
"database": {
"port": 9000
},
"ui": {
"enabled": true
}
}
}
I changed rules just in case:
{
"rules": {
".read": true,
".write": true
}
}
but its not that.
and here is how I try to connect to database in my iOS application(my FirebaseManager class):
init(){
Auth.auth().useEmulator(withHost:"192.168.1.3", port:9099)
}
private lazy var newsNodeRef:DatabaseReference? = {
guard let urlString = getBaseURL() else {return nil}
let node = LocalConstants.kNewsRef // this has value of 'news'
return Database.database(url: urlString).reference(withPath: node)
}()
private func getBaseURL()->String?{
let environment = Environment()
guard let connectionProtocol = environment.configuration(PlistKey.firebaseConnectionProtocol), let baseURL = environment.configuration(PlistKey.firebaseDatabaseURL) else {return nil}
let urlString = "\(connectionProtocol)://\(baseURL)"
return urlString // this produces something like 'http://192.168.1.3:9000?ns=my-project' (its fetched from Configuration Settings file based on selected environment)
}
the thing is, the exact same setup works on remote server, if I just change the environment(which automatically changes base url).
I have also allowed insecure http loads in info.plist, just to be sure if it is not that, but still doesn't work.
This is what I get in console when I run emulators:
What is the problem here?
I replied a little late 😊.
I saw the solution you found. It didn't work for me but I'm sure it has worked for a lot of people.
I found a solution too.
Actually, I couldn't see a problem for iOS 15. My problem was that it didn't work on iOS 14 and earlier.
Solution;
First, you need the MacBook's IP address.
To find the IP address;
You can access it right under System preferences -> Network -> Status.
Then we need to make some changes in the firebase.json file.
Adding “host” : “IP” for each part.
Overwrite the “host” part with the “port” part.
"emulators": {
"auth": {
"host": "192.168.1.11”,
"port": 9100
},
"functions": {
"host": "192.168.1.11”,
"port": 5002
},
"firestore": {
"host": "192.168.1.11”,
"port": 8081
},
"database": {
"host": "192.168.1.11",
"port": 9001
},
"storage": {
"host": "192.168.1.11",
"port": 9200
},
"ui": {
"enabled": true
}
Then we need to add in swift codes.
We need to write the IP address in the host part.
More precisely, we will replace the parts that say localhost with the IP address.
let settings = Firestore.firestore().settings
settings.host = "192.168.1.11:8081"
settings.isPersistenceEnabled = false
settings.isSSLEnabled = false
Firestore.firestore().settings = settings
Storage.storage().useEmulator(withHost:"192.168.1.11", port:9200)
Auth.auth().useEmulator(withHost:"192.168.1.11", port:9100)
let db = Database.database(url:"http://192.168.1.11:9001?ns=firebaseappname")
Functions.functions().useFunctionsEmulator(origin: "http://192.168.1.11:5002")
I think this solution will work in JS, android and other languages.
I would appreciate it if you tried this solution and let me know if it works.
It worked for me.
I actually solved it. The solution/problem, I don't even know how to declare it, was with Local Network Access prompt & permissions and its buggy behaviour (as well how I was trying to access my Mac by ip).
At first I didn't even see a prompt shows every time, but I guess it was related to a wrong setup of a port, host etc.
But when I correctly set local computer's ip and reverted firebase.json to it's default settings (which is what worked for me), the prompt started to jump out every time.
The thing is, prompt's behaviour seems broken, because instead of jumping before you try to access devices in a local network, it pops out after that action is made. Quite fast, but still after Auth system responded, which doesn't make sense.
Here, it can be confusing, cause error that is returned from a Firebase Auth system in the case when you didn't allow Local Network Access usage, doesn't really tell you much about real cause. See my ( original question) above to see the errors.
After that terrible flow, I allowed access trough the prompt. Once I did that, on every next 'api' call towards Emulator was successful. Worked like a charm.
The real problem here is Local Network Access prompt. Cause we don't have at all control over it, so we can't that easily trigger it, or easily get info what user have selected/chosen at the moment / or before. It's triggered by the system in certain conditions.
Luckily this is just for development :) but I hope it will be fixed/improved soon, cause it should.
I found a lot about this topic and its considered as a bug Local Network Access Prompt problems on Dev portal:
I was also faced the same problem while using the firebase auth in iOS simulator
then i change my code little bit
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
if (Platform.isAndroid) {
await FirebaseAuth.instance.useAuthEmulator('localhost', 9099);
}
runApp(const MyApp());
}
I have made a check for only android and it works for me
Inside this method you can see it only works for android.
I'm tring to deploy a simple test app on cloud with digital ocean.
I created a new app with the vue cli (VUE3).
After i dockerized the app and exposed to 8080.
I configured the nginx so that it route traffic from port :80 to :8080 on the container.
Everything is ok, but when i try to visit the page i got this error "Invalid host header".
I searched on google and everybody suggest to create a vue.config.js file with this code:
module.exports = {
devServer: {
disableHostCheck: true
} }
I tried this solution but nothing is changed. How can i fix this error?
I also read that this kind of solution create vulnerabilities, is there a way to fix without this solution?
Thank you in advance for the response
In your vue.config.js file you can try this settings
const { defineConfig } = require('#vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
allowedHosts: "all"
}
})
Found the solution!
The mentioned solutions above does not work for me.
I am not sure when the property allowedHosts was changed.
currently, we supposed to provide an array to the allowedHosts property.
devServer: {
allowedHosts: [
'yourdomain.com'
]
}
Just look for the file vue.config.js, then replace: yourdomain.com with your own personal domain.
An alternative to Oren Hahiashvili's answer when you don't know ahead of time what hosts will be accessing the devServer (e.g., when testing on multiple environments) is to set devServer.diableHostCheck in vue.config.js. For example,
module.exports = {
devServer: {
disableHostCheck: true
}
};
Note this is less secure than Oren Hahiashvili's answer, so only use this when you don't know the hosts, and you still need to serve using devServer.
Please do not mark as duplicate. This is not an exact duplicate of the other similar questions here on SO. It's more specific and fully reproducible.
Clone this repo.
yarn && yarn dev
Go to localhost:3000 and make sure under (F12)->Applications->Service workers, the service worker is installed.
Go to Network tab and refresh a few times(F5)
Observe how the network requests are doubled.
Example of what I see:
Or if you want to do it manually follow the instructions below:
yarn create-next-app app_name
cd app_name && yarn
in public folder, create file called service-worker.js and paste the following code:
addEventListener("install", (event) => {
self.skipWaiting();
console.log("Service worker installed!");
});
self.addEventListener("fetch", (event) => {
event.respondWith(
(async function () {
const promiseChain = fetch(event.request.clone()); // clone makes no difference
event.waitUntil(promiseChain); // makes no difference
return promiseChain;
})()
);
});
open pages/index.js and just below import Head from "next/head"; paste the following code:
if (typeof window !== "undefined" && "serviceWorker" in navigator) {
window.addEventListener("load", function () {
// there probably needs to be some check if sw is already registered
navigator.serviceWorker
.register("/service-worker.js", { scope: "/" })
.then(function (registration) {
console.log("SW registered: ", registration);
})
.catch(function (registrationError) {
console.log("SW registration failed: ", registrationError);
});
});
}
yarn dev
go to localhost:3000 and make sure the service worker has been loaded under (F12)Applications/Service Workers
Go to the Network tab and refresh the page a few times. See how the service worker sends two requests for each one
What do I need to change in the service-worker.js code so that there are no double requests?
This is how Chrome DevTools shows requests and is expected.
There is a request for a resource from the client JavaScript to the Service Worker and a request from the Service Worker to the server. This will always happen unless the service worker has the response cached and does not need to check the server for an update.
Does not seems the right way to initialize service worker in Next.js.You may need to look into next-pwa plugin to do it right.Here is the tutorial PWA with Next.js
If anyone is looking for an answer to the original question 'What to change to prevent double request from service worker?', specifically for network requests.
I've found a way to prevent it. Use the following in the serviceworker.js. (This also works for api calls etc.)
self.addEventListener('fetch', async function(event) {
await new Promise(function(res){setTimeout(function(){res("fetch request allowed")}, 9999)})
return false
});
I built an app using create react which by default includes a service worker. I want the app to be run anytime someone enters the given url except when they go to /blog/, which is serving a set of static content. I use react router in the app to catch different urls.
I have nginx setup to serve /blog/ and it works fine if someone visits /blog/ without visiting the react app first. However because the service worker has a scope of ./, anytime someone visits any url other than /blog/, the app loads the service worker. From that point on, the service worker bypasses a connection to the server and /blog/ loads the react app instead of the static contents.
Is there a way to have the service worker load on all urls except /blog/?
So, considering, you have not posted any code relevant to the service worker, you might consider adding a simple if conditional inside the code block for fetch
This code block should already be there inside your service worker.Just add the conditionals
self.addEventListener( 'fetch', function ( event ) {
if ( event.request.url.match( '^.*(\/blog\/).*$' ) ) {
return false;
}
// OR
if ( event.request.url.indexOf( '/blog/' ) !== -1 ) {
return false;
}
// **** rest of your service worker code ****
note you can either use the regex or the prototype method indexOf.
per your whim.
the above would direct your service worker, to just do nothing when the url matches /blog/
Another way to blacklist URLs, i.e., exclude them from being served from cache, when you're using Workbox can be achieved with workbox.routing.registerNavigationRoute:
workbox.routing.registerNavigationRoute("/index.html", {
blacklist: [/^\/api/,/^\/admin/],
});
The example above demonstrates this for a SPA where all routes are cached and mapped into index.html except for any URL starting with /api or /admin.
here's whats working for us in the latest CRA version:
// serviceWorker.js
window.addEventListener('load', () => {
if (isAdminRoute()) {
console.info('unregistering service worker for admin route')
unregister()
console.info('reloading')
window.location.reload()
return false
}
we exclude all routes under /admin from the server worker, since we are using a different app for our admin area. you can change it of course for anything you like, here's our function in the bottom of the file:
function isAdminRoute() {
return window.location.pathname.startsWith('/admin')
}
Here's how you do it in 2021:
import {NavigationRoute, registerRoute} from 'workbox-routing';
const navigationRoute = new NavigationRoute(handler, {
allowlist: [
new RegExp('/blog/'),
],
denylist: [
new RegExp('/blog/restricted/'),
],
});
registerRoute(navigationRoute);
How to Register a Navigation Route
If you are using or willing to use customize-cra, the solution is quite straight-forward.
Put this in your config-overrides.js:
const { adjustWorkbox, override } = require("customize-cra");
module.exports = override(
adjustWorkbox(wb =>
Object.assign(wb, {
navigateFallbackWhitelist: [
...(wb.navigateFallbackWhitelist || []),
/^\/blog(\/.*)?/,
],
})
)
);
Note that in the newest workbox documentation, the option is called navigateFallbackAllowlist instead of navigateFallbackWhitelist. So, depending on the version of CRA/workbox you use, you might need to change the option name.
The regexp /^/blog(/.*)?/ matches /blog, /blog/, /blog/abc123 etc.
Try using the sw-precache library to overwrite the current service-worker.js file that is running the cache strategy. The most important part is setting up the config file (i will paste the one I used with create-react-app below).
Install yarn sw-precache
Create and specify the config file which indicates which URLs to not cache
modify the build script command to make sure sw-precache runs and overwrites the default service-worker.js file in the build output directory
I named my config file sw-precache-config.js is and specified it in build script command in package.json. Contents of the file are below. The part to pay particular attention to is the runtimeCaching key/option.
"build": "NODE_ENV=development react-scripts build && sw-precache --config=sw-precache-config.js"
CONFIG FILE: sw-precache-config.js
module.exports = {
staticFileGlobs: [
'build/*.html',
'build/manifest.json',
'build/static/**/!(*map*)',
],
staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
swFilePath: './build/service-worker.js',
stripPrefix: 'build/',
runtimeCaching: [
{
urlPattern: /dont_cache_me1/,
handler: 'networkOnly'
}, {
urlPattern: /dont_cache_me2/,
handler: 'networkOnly'
}
]
}
Update (new working solution)
In the last major release of Create React App (version 4.x.x), you can easily implement your custom worker-service.js without bleeding. customize worker-service
Starting with Create React App 4, you have full control over customizing the logic in this service worker, by creating your own src/service-worker.js file, or customizing the one added by the cra-template-pwa (or cra-template-pwa-typescript) template. You can use additional modules from the Workbox project, add in a push notification library, or remove some of the default caching logic.
You have to upgrade your react script to version 4 if you are currently using older versions.
Working solution for CRA v4
Add the following code to the file service-worker.js inside the anonymous function in registerRoute-method.
// If this is a backend URL, skip
if (url.pathname.startsWith("/backend")) {
return false;
}
To simplify things, we can add an array list of items to exclude, and add a search into the fetch event listener.
Include and Exclude methods below for completeness.
var offlineInclude = [
'', // index.html
'sitecss.css',
'js/sitejs.js'
];
var offlineExclude = [
'/networkimages/bigimg.png', //exclude a file
'/networkimages/smallimg.png',
'/admin/' //exclude a directory
];
self.addEventListener("install", function(event) {
console.log('WORKER: install event in progress.');
event.waitUntil(
caches
.open(version + 'fundamentals')
.then(function(cache) {
return cache.addAll(offlineInclude);
})
.then(function() {
console.log('WORKER: install completed');
})
);
});
self.addEventListener("fetch", function(event) {
console.log('WORKER: fetch event in progress.');
if (event.request.method !== 'GET') {
console.log('WORKER: fetch event ignored.', event.request.method, event.request.url);
return;
}
for (let i = 0; i < offlineExclude.length; i++)
{
if (event.request.url.indexOf(offlineExclude[i]) !== -1)
{
console.log('WORKER: fetch event ignored. URL in exclude list.', event.request.url);
return false;
}
}
I want to use gulp-webapp with php server (not the default built in one).
my gulp file looks like this, but here is the extracted part:
gulp.task('serve', ['styles'], function () {
browserSync.init("*", {
debugInfo: true,
open: true,
proxy: "localhost/nl_mobile/app"
})
});
gulp.task('watch', ['serve'], function () {
// watch for changes
gulp.watch(['app/*.html'], reload);
gulp.watch('app/styles/**/*.scss', ['styles']);
gulp.watch('app/scripts/**/*.js', ['scripts']);
gulp.watch('app/images/**/*', ['images']);
gulp.watch('bower.json', ['wiredep']);
gulp.watch('app/bower_components/**/*.scss', ['styles']);
gulp.watch('app/bower_components/**/*.js', ['scripts']);
});
The problem is, the changed content inject to the browser but it does not refresh itself, i have to refresh it manually.
I also changed this line:
// .pipe(gulp.dest('.tmp/styles'))
.pipe(gulp.dest('app/styles'))
because, i cannon't specify
server: {
baseDir: ['app', '.tmp'],
directory: true
},
because it will fire up some kind of http based server which doesn't understand php :(
In case you didn't run across the answer already, Browser Sync supports a proxy config option that can be used to reverse proxy another web server, e.g. Apache, php -S. You'll also need to watch the PHP files in your project for updates to trigger the reload in the attached browsers. Happy to expound with examples as needed.