Пример #1
0
        private IDisposable FindAllCommandHolder(ILayoutController content, InterceptState state)
        {
            if (content == null)
            {
                return(null);
            }

            return(FindAllCommandHolder(content.Children.ToArray(), state));
        }
Пример #2
0
        private IDisposable FindAllCommandHolder(IViewContainer <View> content, InterceptState state)
        {
            if (content == null)
            {
                return(null);
            }

            return(FindAllCommandHolder(content.Children.ToArray(), state));
        }
Пример #3
0
        public IObservable <bool> AutomateUserActions(Page page, RxnPageModel model, IObservable <IRxn> actions, Action <IRxn> publish)
        {
            return(RxObservable.DfrCreate <bool>(o =>
            {
                var state = new InterceptState(model, actions, publish);
                var resources = new CompositeDisposable(new DisposableAction(() => { Debug.WriteLine("<<<<Disposing of {0}>>>>>", model.GetType().Name); }));

                if (page is ContentPage)
                {
                    Observable.FromEventPattern(e => page.LayoutChanged += e, e => page.LayoutChanged -= e)
                    .Select(_ => new Unit())
                    .StartWith(new Unit())
                    .BufferFirstLast(TimeSpan.FromMilliseconds(70), false)
                    .Do(_ => o.OnNext(false))
                    .Do(_ => _dialog.ShowLoading("Loading..."))
                    .Do(_ => Debug.WriteLine("Intercepting>>> {0}", model.GetType().Name))

                    .Select(_ =>
                    {
                        return Observable.Defer(() => RxObservable.Create(() =>
                        {
                            var timer = Stopwatch.StartNew();
                            var r = FindAllCommandHolder(((ContentPage)page).Content as IViewContainer <View>, state);
                            timer.Stop();
                            Debug.WriteLine("Interception took: {0}", timer.Elapsed);

                            if (r != null)
                            {
                                resources.Add(r);
                            }
                        }));
                    })
                    .Switch()
                    .Do(_ => _dialog.HideLoading())
                    .FinallyR(() => _dialog.HideLoading())
                    .Subscribe(_ => o.OnNext(true))
                    .DisposedBy(resources);

                    return resources;
                }
                ;

                return Disposable.Empty;
            }));
        }
Пример #4
0
        private IDisposable FindAllCommandHolder(Element[] content, InterceptState state)
        {
            var resources = new CompositeDisposable();

            if (content == null)
            {
                return(null);
            }

            foreach (var child in content)
            {
                //if (state.Searched.Contains(child)) continue;
                //state.Searched.Add(child);

                var container = child as IViewContainer <View>;
                if (container != null)
                {
                    var r1 = FindAllCommandHolder(container, state);
                    if (r1 != null)
                    {
                        resources.Add(r1);
                    }
                }

                var container1 = child as ILayoutController;
                if (container1 != null)
                {
                    var r1 = FindAllCommandHolder(container1, state);
                    if (r1 != null)
                    {
                        resources.Add(r1);
                    }
                }

                var r = InterceptCommand(child, state);
                if (r != null)
                {
                    resources.Add(r);
                }
            }

            return(resources.Count > 0 ? resources : null);
        }
Пример #5
0
        ///the main goal here is that i want to make it
        /// -simple to create UI test
        /// -refactor safe tests, move a command to a different control, the command still works
        /// -support a mode where the taps are executed on the screen, and the resulting command is paired with it
        /// -the interceptor will only activate in UI record mode, and it will generate an extra event, and "UserTapped PropertyName/CommandParameter (serilised)"
        /// -playback will see this usertapped command, search on the page for the first matching combo, and then tap the screen over it and wit for a response to match with the existing recorded response
        private IDisposable InterceptCommand(Element child, InterceptState state)
        {
            var resources = new CompositeDisposable();
            var commands  = CommandOn(child);

            foreach (var hasCommand in commands)
            {
                //Debug.WriteLine("Looking at {0} => {1}", hasCommand.Item1, hasCommand.Item2);
                if (state.Searched.Contains(hasCommand.Item1))
                {
                    continue;
                }
                state.Searched.Add(hasCommand.Item1);

                var value = hasCommand.Item1.GetProperty(hasCommand.Item2);
                if (value != null)
                {
                    var propertyNameOfCommand = PropertyNameOn(state.Model, value) ?? PropertyNameOn(child.BindingContext, value);
                    if (propertyNameOfCommand != null)
                    {
                        var           originalCmd = hasCommand.Item1.GetProperty(hasCommand.Item2) as ICommand;
                        var           propertyNameOfCmdParameter = "{0}Parameter".FormatWith(hasCommand.Item2);
                        var           hasParam        = hasCommand.Item1.HasProperty(propertyNameOfCmdParameter);
                        Func <object> getCmdParameter = () => hasParam?hasCommand.Item1.GetProperty(propertyNameOfCmdParameter) : null;

                        var cmdParameter = getCmdParameter();

                        //two problems currently
                        // - activityInfo references icons filesource, should switch to string binding to image because as cmdParam it has IdGuid
                        // - the pages that load async are causing the commands not to be hooked up. implement IObservable<Unit> SHowBackground and make
                        // - isLoading a vm property. then use this as a sync point, pause the video while pages load? think thats  good idea too
                        var code = GetCode(propertyNameOfCommand, cmdParameter);
                        if (state.Commands.ContainsKey(code))
                        {
                            state.Commands[code]++;
                        }
                        else
                        {
                            state.Commands.Add(code, 0);
                        }
                        var id = state.Commands[code];
                        propertyNameOfCommand = "{0}%{1}".FormatWith(propertyNameOfCommand, id);


                        RxnApp.UIScheduler.Run(() =>
                                               hasCommand.Item1.GetPropertyDef(hasCommand.Item2).SetValue(hasCommand.Item1, new Command(p =>
                        {
                            try
                            {
                                //incase its changed or whoever is implementing ICommand is
                                //dynamically geneerating a parameter on click, lets update
                                cmdParameter = p;
                                state.Publish(new UserExecuted()
                                {
                                    CommandPath = propertyNameOfCommand,
                                    Parameter   = new CP(cmdParameter)
                                });
                            }
                            catch (Exception e)
                            {
                                Debug.WriteLine(e);
                            }
                        })));

                        state.Input.OfType <UserExecuted>()
                        .Where(w =>
                        {
                            return(!hasParam ? w.CommandPath == propertyNameOfCommand : w.CommandPath == propertyNameOfCommand && w.Parameter.PP == cmdParameter);
                        })
                        .Where(ue => originalCmd.CanExecute(ue.Parameter.PP))     //incase of null params, where params are dependent on user input, use the stored value
                        .Do(ue => originalCmd.Execute(ue.Parameter.PP))
                        .Until()
                        .DisposedBy(resources);

                        new DisposableAction(() => hasCommand.Item1.GetPropertyDef(hasCommand.Item2).SetValue(hasCommand.Item1, originalCmd)).DisposedBy(resources);

                        Debug.WriteLine("<Intercepted> [{0}]{1} ->{2}", hasCommand.Item1.GetHashCode(), hasCommand.Item1.GetType().Name, propertyNameOfCommand);
                    }
                }
            }

            return(resources.Count > 0 ? resources : null);
        }